diff --git a/.gitignore b/.gitignore index d12bb97..a137ced 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ # phpstorm project files -.idea \ No newline at end of file +.idea + +composer.phar +composer.lock +vendor \ No newline at end of file diff --git a/ActiveQuery.php b/ActiveQuery.php index 2e8ace7..73b379a 100644 --- a/ActiveQuery.php +++ b/ActiveQuery.php @@ -3,12 +3,9 @@ namespace devgroup\arangodb; use Yii; -use yii\base\InvalidConfigException; use yii\db\ActiveQueryInterface; use yii\db\ActiveQueryTrait; -use yii\db\ActiveRecordInterface; use yii\db\ActiveRelationTrait; -use yii\helpers\VarDumper; use triagens\ArangoDb\Document; @@ -103,18 +100,6 @@ class ActiveQuery extends Query implements ActiveQueryInterface return $models; } - private function prefixKeyColumns($attributes) - { - if ($this instanceof ActiveQuery) { - /* @var $modelClass ActiveRecord */ - $modelClass = $this->modelClass; - foreach ($attributes as $i => $attribute) { - $attributes[$i] = "{$modelClass::collectionName()}.$attribute"; - } - } - return $attributes; - } - public function all($db = null) { $statement = $this->createCommand($db); diff --git a/ActiveRecord.php b/ActiveRecord.php index 07797f3..3cfbff4 100644 --- a/ActiveRecord.php +++ b/ActiveRecord.php @@ -5,7 +5,6 @@ namespace devgroup\arangodb; use Yii; use yii\base\ArrayableTrait; use yii\base\InvalidConfigException; -use yii\base\Model; use yii\db\ActiveQueryInterface; use yii\db\BaseActiveRecord; use yii\db\StaleObjectException; @@ -17,16 +16,6 @@ use triagens\ArangoDb\Document; abstract class ActiveRecord extends BaseActiveRecord { - /** @var Document $document */ - private $document; - - public function __construct($config = []) - { - $this->document = new Document(); - - parent::__construct($config); - } - public function mergeAttribute($name, $value) { $newValue = $this->getAttribute($name); @@ -47,12 +36,6 @@ abstract class ActiveRecord extends BaseActiveRecord return Inflector::camel2id(StringHelper::basename(get_called_class()), '_'); } - public function setAttribute($name, $value) - { - $this->document->set($name, $value); - parent::setAttribute($name, $value); - } - /** * Returns the primary key **name(s)** for this AR class. * @@ -113,11 +96,11 @@ abstract class ActiveRecord extends BaseActiveRecord * } * * // Use andWhere()/orWhere() to apply the default condition - * // SELECT FROM customer WHERE `deleted`=:deleted AND age>30 + * // FOR customer IN customer FILTER customer.deleted=:deleted AND customer.age>30 RETURN customer * $customers = Customer::find()->andWhere('age>30')->all(); * * // Use where() to ignore the default condition - * // SELECT FROM customer WHERE age>30 + * // FOR customer IN customer FILTER customer.age>30 RETURN customer * $customers = Customer::find()->where('age>30')->all(); * * @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance. @@ -137,13 +120,10 @@ abstract class ActiveRecord extends BaseActiveRecord */ public static function populateRecord($record, $row) { - if (is_array($row)) { - $document = Document::createFromArray($row); - } else { - $document = $row; + if ($row instanceof Document) { $row = $row->getAll(); } - $record->document = $document; + parent::populateRecord($record, $row); } @@ -206,7 +186,7 @@ abstract class ActiveRecord extends BaseActiveRecord $this->setIsNewRecord(false); $changedAttributes = array_fill_keys(array_keys($values), null); - $this->setOldAttributes($this->document->getAll()); + $this->setOldAttributes($values); $this->afterSave(true, $changedAttributes); return true; @@ -235,10 +215,12 @@ abstract class ActiveRecord extends BaseActiveRecord $this->setAttribute($key, $attribute); } - $rows = static::getDb()->getDocumentHandler()->updateById( + $rows = (new Query())->update( static::collectionName(), - $this->getOldAttribute('_key'), - Document::createFromArray($values) + $values, + [ + '_key' => $this->getOldAttribute('_key'), + ] ); if ($lock !== null && !$rows) { @@ -300,20 +282,7 @@ abstract class ActiveRecord extends BaseActiveRecord */ public static function updateAll($attributes, $condition = []) { - $docs = static::findAll($condition); - - $count = 0; - foreach ($docs as $doc) { - foreach ($attributes as $key => $attribute) { - $doc->setAttribute($key, $attribute); - $doc->document->set($key, $attribute); - } - if (static::getDb()->getDocumentHandler()->update($doc->document)) { - $count++; - } - } - - return $count; + return (new Query())->update(static::collectionName(), $attributes, $condition); } /** @@ -331,19 +300,9 @@ abstract class ActiveRecord extends BaseActiveRecord * An empty condition will match all records. * @return integer the number of rows deleted */ - public static function deleteAll($condition = null) + public static function deleteAll($condition = []) { - /** @var Document[] $docs */ - $records = static::findAll($condition); - - $count = 0; - foreach ($records as $record) { - if (static::getDb()->getDocumentHandler()->remove($record->document)) { - $count++; - } - } - - return $count; + return (new Query())->remove(static::collectionName(), $condition); } public static function truncate() @@ -410,7 +369,7 @@ abstract class ActiveRecord extends BaseActiveRecord if ($lock !== null) { $condition[$lock] = $this->$lock; } - $result = static::getDb()->getDocumentHandler()->removeById(static::collectionName(), $condition); + $result = (new Query())->remove(static::collectionName(), $condition); if ($lock !== null && !$result) { throw new StaleObjectException('The object being deleted is outdated.'); } @@ -419,20 +378,6 @@ abstract class ActiveRecord extends BaseActiveRecord return $result; } - /** - * Returns a value indicating whether the current record is new (not saved in the database). - * @return boolean whether the record is new and should be inserted when calling [[save()]]. - */ - public function getIsNewRecord() - { - return $this->document->getIsNew(); - } - - public function setIsNewRecord($value) - { - $this->document->setIsNew($value); - } - public function init() { parent::init(); diff --git a/Migration.php b/Migration.php index ef33ee2..a73f71b 100644 --- a/Migration.php +++ b/Migration.php @@ -2,7 +2,6 @@ namespace devgroup\arangodb; -use triagens\ArangoDb\Document; use yii\base\Component; use yii\db\MigrationInterface; use yii\di\Instance; @@ -40,11 +39,11 @@ abstract class Migration extends Component implements MigrationInterface echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } - public function insert($collection, $columns) + public function insert($collection, $columns, $params = []) { echo " > insert into $collection ..."; $time = microtime(true); - $this->db->getDocumentHandler()->save($collection, $columns); + (new Query())->insert($collection, $columns, $params); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } @@ -52,10 +51,7 @@ abstract class Migration extends Component implements MigrationInterface { echo " > update $collection ..."; $time = microtime(true); - $docs = (new Query())->select($collection)->from($collection)->where($condition, $params)->all(); - foreach ($docs as $doc) { - $this->db->getDocumentHandler()->updateById($collection, $doc['_key'], Document::createFromArray($columns)); - } + (new Query())->update($collection, $columns, $condition, $params); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } @@ -63,10 +59,7 @@ abstract class Migration extends Component implements MigrationInterface { echo " > delete from $collection ..."; $time = microtime(true); - $docs = (new Query())->select($collection)->from($collection)->where($condition, $params)->all(); - foreach ($docs as $doc) { - $this->db->getDocumentHandler()->removeById($collection, $doc['_key']); - } + (new Query())->remove($collection, $condition, $params); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } diff --git a/Query.php b/Query.php index ba9de9e..03513ea 100644 --- a/Query.php +++ b/Query.php @@ -2,8 +2,9 @@ namespace devgroup\arangodb; -use triagens\ArangoDb\Document; use Yii; +use triagens\ArangoDb\Document; +use triagens\ArangoDb\Statement; use yii\base\Component; use yii\base\InvalidParamException; use yii\base\NotSupportedException; @@ -11,9 +12,6 @@ use yii\db\QueryInterface; use yii\helpers\ArrayHelper; use yii\helpers\Json; -use triagens\ArangoDb\Statement; -use yii\helpers\VarDumper; - class Query extends Component implements QueryInterface { const PARAM_PREFIX = 'qp'; @@ -470,6 +468,117 @@ class Query extends Component implements QueryInterface return empty($result) ? false : $result[0]; } + public function insert($collection, $columns, $params = [], $db = null) + { + $doc = Json::encode($columns); + + $aql = "INSERT $doc IN {$this->quoteCollectionName($collection)}"; + + $options = ArrayHelper::merge( + $params, + [ + 'query' => $aql, + ] + ); + + $statement = $this->getStatement($options, $db); + $token = $this->getRawAql($statement); + Yii::info($token, 'devgroup\arangodb\Query::insert'); + try { + Yii::beginProfile($token, 'devgroup\arangodb\Query::insert'); + $cursor = $statement->execute(); + Yii::endProfile($token, 'devgroup\arangodb\Query::insert'); + } catch (\Exception $ex) { + Yii::endProfile($token, 'devgroup\arangodb\Query::insert'); + throw new \Exception($ex->getMessage(), (int) $ex->getCode(), $ex); + } + return true; + } + + public function update($collection, $columns, $condition = [], $params = [], $db = null) + { + $this->from($collection); + $clauses = [ + $this->buildFrom($collection), + $this->buildWhere($condition, $params), + $this->buildUpdate($collection, $columns), + ]; + + $aql = implode($this->separator, array_filter($clauses)); + + $options = ArrayHelper::merge( + $params, + [ + 'query' => $aql, + 'bindVars' => $params, + ] + ); + + $statement = $this->getStatement($options, $db); + $token = $this->getRawAql($statement); + Yii::info($token, 'devgroup\arangodb\Query::update'); + try { + Yii::beginProfile($token, 'devgroup\arangodb\Query::update'); + $cursor = $statement->execute(); + Yii::endProfile($token, 'devgroup\arangodb\Query::update'); + } catch (\Exception $ex) { + Yii::endProfile($token, 'devgroup\arangodb\Query::update'); + throw new \Exception($ex->getMessage(), (int) $ex->getCode(), $ex); + } + $meta = $cursor->getMetadata(); + return isset($meta['extra']['operations']['executed']) ? + $meta['extra']['operations']['executed'] : + true; + } + + public function remove($collection, $condition = [], $params = [], $db = null) + { + $this->from($collection); + $clauses = [ + $this->buildFrom($collection), + $this->buildWhere($condition, $params), + $this->buildRemove($collection), + ]; + + $aql = implode($this->separator, array_filter($clauses)); + + $options = ArrayHelper::merge( + $params, + [ + 'query' => $aql, + 'bindVars' => $params, + ] + ); + + $statement = $this->getStatement($options, $db); + $token = $this->getRawAql($statement); + Yii::info($token, 'devgroup\arangodb\Query::remove'); + try { + Yii::beginProfile($token, 'devgroup\arangodb\Query::remove'); + $cursor = $statement->execute(); + Yii::endProfile($token, 'devgroup\arangodb\Query::remove'); + } catch (\Exception $ex) { + Yii::endProfile($token, 'devgroup\arangodb\Query::remove'); + throw new \Exception($ex->getMessage(), (int) $ex->getCode(), $ex); + } + $meta = $cursor->getMetadata(); + return isset($meta['extra']['operations']['executed']) ? + $meta['extra']['operations']['executed'] : + true; + } + + protected function buildUpdate($collection, $columns) + { + return 'UPDATE ' . $collection . ' WITH ' + . Json::encode($columns) . ' IN ' + . $this->quoteCollectionName($collection); + } + + protected function buildRemove($collection) + { + return 'REMOVE ' . $collection . ' IN ' . $collection; + } + /** * @param Document[] $rows * @return array diff --git a/composer.json b/composer.json index ce3d828..4706d41 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,14 @@ "email": "fps.06@mail.ru" } ], + "minimum-stability": "dev", "require": { "yiisoft/yii2": "*", "triagens/arangodb": "*" }, + "require-dev": { + "yiisoft/yii2-debug": "*" + }, "autoload": { "psr-4": { "devgroup\\arangodb\\": "" diff --git a/console/controllers/MigrateController.php b/console/controllers/MigrateController.php index 0faacea..498204a 100644 --- a/console/controllers/MigrateController.php +++ b/console/controllers/MigrateController.php @@ -11,8 +11,6 @@ use yii; use yii\console\controllers\BaseMigrateController; use yii\helpers\ArrayHelper; -use triagens\ArangoDb\ServerException; - class MigrateController extends BaseMigrateController { /** diff --git a/panels/arangodb/ArangoDbPanel.php b/panels/arangodb/ArangoDbPanel.php index 52954ea..8cd4a22 100644 --- a/panels/arangodb/ArangoDbPanel.php +++ b/panels/arangodb/ArangoDbPanel.php @@ -33,6 +33,9 @@ class ArangoDbPanel extends Panel Logger::LEVEL_PROFILE, [ 'devgroup\arangodb\Query::query', + 'devgroup\arangodb\Query::insert', + 'devgroup\arangodb\Query::update', + 'devgroup\arangodb\Query::remove', 'devgroup\arangodb\Query::execute', ] ); diff --git a/panels/arangodb/models/ArangoDb.php b/panels/arangodb/models/ArangoDb.php index e7747f8..7609189 100644 --- a/panels/arangodb/models/ArangoDb.php +++ b/panels/arangodb/models/ArangoDb.php @@ -2,6 +2,7 @@ namespace devgroup\arangodb\panels\arangodb\models; +use yii; use yii\data\ArrayDataProvider; use yii\debug\components\search\Filter; use yii\debug\models\search\Base;