From ef672ed6b16ee5b2464412dbc79bd2f5a07fd635 Mon Sep 17 00:00:00 2001 From: Ryan Smith <0ryansmith1994@gmail.com> Date: Mon, 17 Aug 2015 10:26:38 +0100 Subject: [PATCH 1/4] Improves performance of migration. --- ...08_12_150203_ConsistentForeignKeyNames.php | 93 +++++++++---------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/app/database/migrations/2015_08_12_150203_ConsistentForeignKeyNames.php b/app/database/migrations/2015_08_12_150203_ConsistentForeignKeyNames.php index 9d43bf4426..8027673441 100644 --- a/app/database/migrations/2015_08_12_150203_ConsistentForeignKeyNames.php +++ b/app/database/migrations/2015_08_12_150203_ConsistentForeignKeyNames.php @@ -5,63 +5,56 @@ class ConsistentForeignKeyNames extends Migration { public function up() { - $this->chunkKeyRenaming(new DocumentAPI, 'lrs', 'lrs_id'); - $this->chunkKeyRenaming(new Statement, 'lrs._id', 'lrs_id'); - $this->chunkKeyRenaming(new Lrs, 'owner._id', 'owner_id'); - $this->chunkKeyRenaming(new Report, 'lrs', 'lrs_id'); - $this->chunkKeyRenaming(new Export, 'lrs', 'lrs_id'); - } - - public function down() { - $this->chunkMongoIdRemoval(new DocumentAPI, 'lrs', 'lrs_id'); - $this->chunkMongoIdRemoval(new Statement, 'lrs._id', 'lrs_id'); - $this->chunkMongoIdRemoval(new Lrs, 'owner._id', 'owner_id'); - $this->chunkMongoIdRemoval(new Report, 'lrs', 'lrs_id'); - $this->chunkMongoIdRemoval(new Export, 'lrs', 'lrs_id'); - } + $db = \DB::getMongoDB(); - private function chunkKeyRenaming($model, $old_name, $new_name) { - $this->chunkModelMigration($model, $this->renameKey($old_name, $new_name)); - } + Lrs::get()->each(function (Lrs $lrs) use ($db) { + $convertToMongoId = function ($value) { + return new \MongoId($value); + }; + $this->changeForeignKey($db->statements, 'lrs._id', 'lrs_id', $lrs->_id, $convertToMongoId); + $this->changeForeignKey($db->documentapi, 'lrs', 'lrs_id', $lrs->_id, $convertToMongoId); + $this->changeForeignKey($db->reports, 'lrs', 'lrs_id', $lrs->_id, $convertToMongoId); + $this->changeForeignKey($db->exports, 'lrs', 'lrs_id', $lrs->_id, $convertToMongoId); - private function chunkMongoIdRemoval($model, $old_name, $new_name) { - $this->chunkModelMigration($model, $this->removeMongoId($old_name, $new_name)); - } + $lrs->owner_id = $convertToMongoId($lrs->owner['_id']); + $lrs->save(); - private function removeMongoId($old_name, $new_name) { - return function ($model) use ($old_name, $new_name) { - $value = $model->$new_name; - $model = $this->setKey($model, explode('.', $old_name), 0, (string) $value); - $model->save(); - }; - } + echo 'Models for "'.$lrs->title.'" converted.'.PHP_EOL; + }); - private function setKey($model, $keys, $key_index, $value) { - if ($key_index < count($keys) - 1) { - $model->{$keys[$key_index]} = (object) []; - $this->setKey($model->{$keys[$key_index]}, $keys, $key_index + 1, $value); - } else { - $model->{$keys[$key_index]} = $value; - } - return $model; - } + echo 'All finished, hopefully!'.PHP_EOL; + } - private function renameKey($old_name, $new_name) { - return function ($model) use ($old_name, $new_name) { - $value = array_reduce(explode('.', $old_name), function ($value, $key) { - return is_object($value) ? $value->{$key} : $value[$key]; - }, $model); - $model->$new_name = new \MongoId($value); - $model->save(); - }; + private function changeForeignKey($collection, $old_key, $new_key, $old_value, $modifier) { + $collection->update([ + $old_key => $old_value + ], [ + '$set' => [ + $new_key => $modifier($old_value) + ] + ], [ + 'multiple' => true + ]); } - private function chunkModelMigration($model, Callable $migration) { - $model->chunk(1000, function ($models) use ($migration) { - foreach ($models as $model){ - $migration($model); - } - echo count($models) . ' converted.'.PHP_EOL; + public function down() { + $db = \DB::getMongoDB(); + + Lrs::get()->each(function (Lrs $lrs) use ($db) { + $convertToString = function ($value) { + return (string) $value; + }; + $this->changeForeignKey($db->statements, 'lrs_id', 'lrs._id', $lrs->_id, $convertToString); + $this->changeForeignKey($db->documentapi, 'lrs_id', 'lrs', $lrs->_id, $convertToString); + $this->changeForeignKey($db->reports, 'lrs_id', 'lrs', $lrs->_id, $convertToString); + $this->changeForeignKey($db->exports, 'lrs_id', 'lrs', $lrs->_id, $convertToString); + + $lrs->owner = [ + '_id' => $convertToString($lrs->owner_id) + ]; + $lrs->save(); + + echo 'Models for "'.$lrs->title.'" converted.'.PHP_EOL; }); echo 'All finished, hopefully!'.PHP_EOL; From c60cd9777cee9e2057b4fab578d754ddc54243fd Mon Sep 17 00:00:00 2001 From: Ryan Smith <0ryansmith1994@gmail.com> Date: Wed, 19 Aug 2015 11:32:45 +0100 Subject: [PATCH 2/4] Updates test script. --- test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.sh b/test.sh index 8fa05e7554..f66a8a7dfd 100644 --- a/test.sh +++ b/test.sh @@ -13,10 +13,10 @@ if [ "${DEVELOP}" = "${TRAVIS_BRANCH}" ]; then mongo ll_staging --eval 'db.users.insert({"name" : "Test User", "email" : "test@example.com", "verified" : "yes", "role" : "super", "password" : "$2y$10$MKDC2thihULF3fNuVj.DyORidVd.airmxZicEcSrpNQRsJMX3ZGBW"})' # Creates a new LRS. - mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner" : { "_id" : db.users.find()[0]._id}})' + mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner_id" : new ObjectId(db.users.find()[0]._id)}})' # Creates a new Client. - mongo ll_staging --eval 'db.client.insert({"api" : { "basic_key" : "1484c2ac05269b8c5479a1dd6a0d6370991fd6a1", "basic_secret" : "f0ef3d8062805c0fc1675beb8ac0715c75df13cb" }, "lrs_id" : db.lrs.find()[0]._id, "authority" : { "name" : "New Client", "mbox" : "mailto:hello@learninglocker.net" }, "scopes" : [ "all" ]})' + mongo ll_staging --eval 'db.client.insert({"api" : { "basic_key" : "1484c2ac05269b8c5479a1dd6a0d6370991fd6a1", "basic_secret" : "f0ef3d8062805c0fc1675beb8ac0715c75df13cb" }, "lrs_id" : new ObjectId(db.lrs.find()[0]._id), "authority" : { "name" : "New Client", "mbox" : "mailto:hello@learninglocker.net" }, "scopes" : [ "all" ]})' # Runs the test suite. git clone https://github.com/ryansmith94/xAPI_LRS_Test.git conformance > /dev/null From 96c1529b06a3ed45a2d5bcd3e4dafd6a9242bac4 Mon Sep 17 00:00:00 2001 From: Ryan Smith <0ryansmith1994@gmail.com> Date: Wed, 19 Aug 2015 11:40:17 +0100 Subject: [PATCH 3/4] Corrects syntax. --- test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.sh b/test.sh index f66a8a7dfd..f1344b953e 100644 --- a/test.sh +++ b/test.sh @@ -13,7 +13,7 @@ if [ "${DEVELOP}" = "${TRAVIS_BRANCH}" ]; then mongo ll_staging --eval 'db.users.insert({"name" : "Test User", "email" : "test@example.com", "verified" : "yes", "role" : "super", "password" : "$2y$10$MKDC2thihULF3fNuVj.DyORidVd.airmxZicEcSrpNQRsJMX3ZGBW"})' # Creates a new LRS. - mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner_id" : new ObjectId(db.users.find()[0]._id)}})' + mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner_id" : new ObjectId(db.users.find()[0]._id)})' # Creates a new Client. mongo ll_staging --eval 'db.client.insert({"api" : { "basic_key" : "1484c2ac05269b8c5479a1dd6a0d6370991fd6a1", "basic_secret" : "f0ef3d8062805c0fc1675beb8ac0715c75df13cb" }, "lrs_id" : new ObjectId(db.lrs.find()[0]._id), "authority" : { "name" : "New Client", "mbox" : "mailto:hello@learninglocker.net" }, "scopes" : [ "all" ]})' From 40f1bbbe3ad57ce29380b88a5878b9a3c803ae5c Mon Sep 17 00:00:00 2001 From: Ryan Smith <0ryansmith1994@gmail.com> Date: Wed, 19 Aug 2015 11:45:42 +0100 Subject: [PATCH 4/4] Corrects test script. --- test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.sh b/test.sh index f1344b953e..4601678b67 100644 --- a/test.sh +++ b/test.sh @@ -13,10 +13,10 @@ if [ "${DEVELOP}" = "${TRAVIS_BRANCH}" ]; then mongo ll_staging --eval 'db.users.insert({"name" : "Test User", "email" : "test@example.com", "verified" : "yes", "role" : "super", "password" : "$2y$10$MKDC2thihULF3fNuVj.DyORidVd.airmxZicEcSrpNQRsJMX3ZGBW"})' # Creates a new LRS. - mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner_id" : new ObjectId(db.users.find()[0]._id)})' + mongo ll_staging --eval 'db.lrs.insert({"title" : "Conformance", "description" : "", "owner_id" : db.users.find()[0]._id})' # Creates a new Client. - mongo ll_staging --eval 'db.client.insert({"api" : { "basic_key" : "1484c2ac05269b8c5479a1dd6a0d6370991fd6a1", "basic_secret" : "f0ef3d8062805c0fc1675beb8ac0715c75df13cb" }, "lrs_id" : new ObjectId(db.lrs.find()[0]._id), "authority" : { "name" : "New Client", "mbox" : "mailto:hello@learninglocker.net" }, "scopes" : [ "all" ]})' + mongo ll_staging --eval 'db.client.insert({"api" : { "basic_key" : "1484c2ac05269b8c5479a1dd6a0d6370991fd6a1", "basic_secret" : "f0ef3d8062805c0fc1675beb8ac0715c75df13cb" }, "lrs_id" : db.lrs.find()[0]._id, "authority" : { "name" : "New Client", "mbox" : "mailto:hello@learninglocker.net" }, "scopes" : [ "all" ]})' # Runs the test suite. git clone https://github.com/ryansmith94/xAPI_LRS_Test.git conformance > /dev/null