-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
started work on Migration support for elasticsearch
issue #6712
- Loading branch information
Showing
5 changed files
with
293 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
<?php | ||
/** | ||
* @link http://www.yiiframework.com/ | ||
* @copyright Copyright (c) 2008 Yii Software LLC | ||
* @license http://www.yiiframework.com/license/ | ||
*/ | ||
|
||
namespace yii\elasticsearch; | ||
|
||
use Yii; | ||
use yii\console\controllers\BaseMigrateController; | ||
use yii\console\Exception; | ||
use yii\di\Instance; | ||
use yii\helpers\ArrayHelper; | ||
use yii\helpers\Console; | ||
|
||
/** | ||
* Manages application migrations using Elasticsearch. | ||
* | ||
* This is an analog of [[\yii\console\controllers\MigrateController]] but for Elasticsearch. | ||
* | ||
* This command provides support for tracking the migration history, upgrading | ||
* or downloading with migrations, and creating new migration skeletons. | ||
* | ||
* The migration history is stored in a Elasticsearch index/type specified by [[index]] and [[type]]. | ||
* This index will be automatically created the first time this command is executed, if it does not exist. | ||
* | ||
* In order to enable this command you should adjust the configuration of your console application: | ||
* | ||
* ~~~ | ||
* return [ | ||
* // ... | ||
* 'controllerMap' => [ | ||
* 'es-migrate' => 'yii\elasticsearch\MigrateController', | ||
* 'index' => 'myindex', // set this to the index you want to use to store migration state | ||
* 'type' => 'migrations', | ||
* ], | ||
* ]; | ||
* ~~~ | ||
* | ||
* Below are some common usages of this command: | ||
* | ||
* ~~~ | ||
* # creates a new migration named 'create_user_index' | ||
* yii es-migrate/create create_user_index | ||
* | ||
* # applies ALL new migrations | ||
* yii es-migrate | ||
* | ||
* # reverts the last applied migration | ||
* yii es-migrate/down | ||
* ~~~ | ||
* | ||
* @author Carsten Brandt <mail@cebe.cc> | ||
* @since 2.0.3 | ||
*/ | ||
class MigrateController extends BaseMigrateController | ||
{ | ||
/** | ||
* @var Connection|array|string the DB connection object or the application component ID of the DB connection. | ||
* Starting from version 2.0.2, this can also be a configuration array for creating the object. | ||
*/ | ||
public $db = 'elasticsearch'; | ||
/** | ||
* @var string the name of the index that is used to store migration state. | ||
* Defaults to `yii2`. | ||
* @see type | ||
*/ | ||
public $index = 'yii2'; | ||
/** | ||
* @var string the name of the type that is used to store migration state. | ||
* Defaults to `migrations`. | ||
* @see index | ||
*/ | ||
public $type = 'migrations'; | ||
/** | ||
* @inheritdoc | ||
*/ | ||
public $templateFile = '@yii/mongodb/views/migration.php'; //TODO | ||
|
||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function options($actionID) | ||
{ | ||
return array_merge( | ||
parent::options($actionID), | ||
['index', 'type', 'db'] // global for all actions | ||
); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function beforeAction($action) | ||
{ | ||
if (parent::beforeAction($action)) { | ||
if ($action->id !== 'create') { | ||
$this->db = Instance::ensure($this->db, Connection::className()); | ||
} | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* Creates a new migration instance. | ||
* @param string $class the migration class name | ||
* @return \yii\elasticsearch\Migration the migration instance | ||
*/ | ||
protected function createMigration($class) | ||
{ | ||
$file = $this->migrationPath . DIRECTORY_SEPARATOR . $class . '.php'; | ||
require_once($file); | ||
|
||
return new $class(['db' => $this->db]); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function getMigrationHistory($limit) | ||
{ | ||
$this->ensureBaseMigrationHistory(); | ||
|
||
$query = new Query; | ||
$rows = $query->source(['version', 'apply_time']) | ||
->from($this->index, $this->type) | ||
->orderBy(['version' => SORT_DESC]) | ||
->limit($limit === null ? 10000 : $limit) | ||
->all($this->db); | ||
$history = ArrayHelper::map( | ||
$rows, | ||
function($row) { return $row['_source']['version']; }, | ||
function($row) { return $row['_source']['apply_time']; } | ||
); | ||
unset($history[self::BASE_MIGRATION]); | ||
return $history; | ||
} | ||
|
||
/** | ||
* Ensures migration history contains at least base migration entry. | ||
*/ | ||
protected function ensureBaseMigrationHistory() | ||
{ | ||
$command = $this->db->createCommand(); | ||
if (!$command->typeExists($this->index, $this->type)) { | ||
$this->stdout("Creating migration history index and type \"{$this->index}/{$this->type}\"..."); | ||
|
||
if (!$command->indexExists($this->index)) { | ||
$command->createIndex($this->index); | ||
} | ||
$command->setMapping($this->index, $this->type, [ | ||
$this->migrationTable => [ | ||
"_id" => [ | ||
"index" => "not_analyzed", | ||
"store" => "yes", | ||
"path" => "version" | ||
], | ||
"properties" => [ | ||
"version" => ["type" => "string", "index" => "not_analyzed"], | ||
"apply_time" => ["type" => "integer"], | ||
], | ||
] | ||
]); | ||
$this->stdout("done.\n", Console::FG_GREEN); | ||
} | ||
|
||
$baseMigration = $command->get($this->index, $this->type, self::BASE_MIGRATION); | ||
if ($baseMigration['found'] === false) { | ||
$this->addMigrationHistory(self::BASE_MIGRATION); | ||
} | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function addMigrationHistory($version) | ||
{ | ||
$this->db->createCommand()->insert($this->index, $this->type, [ | ||
'version' => $version, | ||
'apply_time' => time(), | ||
], $version, [ | ||
'op_type' => 'create', | ||
'refresh' => 'true' | ||
]); | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
protected function removeMigrationHistory($version) | ||
{ | ||
$this->db->createCommand()->delete($this->index, $this->type, $version); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
/** | ||
* @link http://www.yiiframework.com/ | ||
* @copyright Copyright (c) 2008 Yii Software LLC | ||
* @license http://www.yiiframework.com/license/ | ||
*/ | ||
|
||
namespace yii\elasticsearch; | ||
|
||
use yii\base\Component; | ||
use yii\db\MigrationInterface; | ||
use yii\di\Instance; | ||
use yii\helpers\Json; | ||
|
||
/** | ||
* Migration is the base class for representing an Elasticsearch migration. | ||
* | ||
* Each child class of Migration represents an individual migration which | ||
* is identified by the child class name. | ||
* | ||
* Within each migration, the [[up()]] method should be overridden to contain the logic | ||
* for "upgrading" the database; while the [[down()]] method for the "downgrading" | ||
* logic. | ||
* | ||
* Migration provides a set of convenient methods for manipulating Elasticsearch data and schema. | ||
* For example, the [[createIndex()]] method can be used to create an index. | ||
* Compared with the same methods in [[Command]], these methods will display extra | ||
* information showing the method parameters and execution time, which may be useful when | ||
* applying migrations. | ||
* | ||
* @author Carsten Brandt <mail@cebe.cc> | ||
* @since 2.0.3 | ||
*/ | ||
abstract class Migration extends Component implements MigrationInterface | ||
{ | ||
/** | ||
* @var Connection|array|string the DB connection object or the application component ID of the DB connection. | ||
* This can also be a configuration array for creating the object. | ||
*/ | ||
public $db = 'elasticsearch'; | ||
|
||
|
||
// TODO pass index and type of the command here | ||
// TODO use reference to the command for output | ||
|
||
/** | ||
* Initializes the migration. | ||
* This method will set [[db]] to be the 'db' application component, if it is null. | ||
*/ | ||
public function init() | ||
{ | ||
parent::init(); | ||
$this->db = Instance::ensure($this->db, Connection::className()); | ||
} | ||
|
||
/** | ||
* Creates a command for execution. | ||
* @param array $config the configuration for the Command class | ||
* @return Command the DB command | ||
*/ | ||
protected function createCommand($config = []) | ||
{ | ||
return $this->db->createCommand($config); | ||
} | ||
|
||
/** | ||
* creates an index | ||
* @param string $index index name. | ||
* @param array $configuration index configuration. | ||
* @return mixed the request result. | ||
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html | ||
*/ | ||
public function createIndex($index, $configuration = null) | ||
{ | ||
echo " > create index \"{$index}\" ..."; | ||
$time = microtime(true); | ||
$this->createCommand()->createIndex($index, $configuration); | ||
echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; | ||
} | ||
|
||
// TODO add more shortcut functions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters