From 9e7b992d92aa1a9ef70ec260ac991cb5c9b5b8d6 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Fri, 3 Feb 2017 23:12:47 -0500 Subject: [PATCH 1/7] Add indexes to link table and use cr32 hashes to increase speed of lookups --- app/Factories/LinkFactory.php | 9 +++++ app/Helpers/LinkHelper.php | 2 +- app/Models/Link.php | 23 ++++++++++++ ...17_02_04_025727_add_link_table_indexes.php | 36 +++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 database/migrations/2017_02_04_025727_add_link_table_indexes.php diff --git a/app/Factories/LinkFactory.php b/app/Factories/LinkFactory.php index cb13d3d..0e468e2 100644 --- a/app/Factories/LinkFactory.php +++ b/app/Factories/LinkFactory.php @@ -7,6 +7,8 @@ use App\Helpers\LinkHelper; class LinkFactory { + const MAXIMUM_LINK_LENGTH = 65535; + private static function formatLink($link_ending, $secret_ending=false) { /** * Given a link ending and a boolean indicating whether a secret ending is needed, @@ -39,6 +41,13 @@ class LinkFactory { * @return string $formatted_link */ + if (strlen($long_url) > self::MAXIMUM_LINK_LENGTH) { + // If $long_url is longer than the maximum length, then + // throw an Exception + throw new \Exception('Sorry, but your link is longer than the + maximum length allowed.'); + } + $is_already_short = LinkHelper::checkIfAlreadyShortened($long_url); if ($is_already_short) { diff --git a/app/Helpers/LinkHelper.php b/app/Helpers/LinkHelper.php index ba9733c..b876d77 100644 --- a/app/Helpers/LinkHelper.php +++ b/app/Helpers/LinkHelper.php @@ -57,7 +57,7 @@ class LinkHelper { * check whether the link is in the DB. * @return boolean */ - $link = Link::where('long_url', $long_url) + $link = Link::longUrl($long_url) ->where('is_custom', 0) ->where('secret_key', '') ->first(); diff --git a/app/Models/Link.php b/app/Models/Link.php index 98ae8c6..9792c94 100644 --- a/app/Models/Link.php +++ b/app/Models/Link.php @@ -4,4 +4,27 @@ use Illuminate\Database\Eloquent\Model; class Link extends Model { protected $table = 'links'; + + public function setLongUrlAttribute($long_url) { + // Set crc32 hash and long_url + // whenever long_url is set on a Link instance + + // Generate 32-bit unsigned integer crc32 value + // Use sprintf to prevent compatibility issues with 32-bit systems + // http://php.net/manual/en/function.crc32.php + $crc32_hash = sprintf('%u', crc32($long_url)); + + $this->attributes['long_url'] = $long_url; + $this->attributes['long_url_hash'] = $crc32_hash; + } + + public function scopeLongUrl($query, $long_url) { + // Allow quick lookups with Link::longUrl that make use + // of the indexed crc32 hash to quickly fetch link + $crc32_hash = sprintf('%u', crc32($long_url)); + + return $query + ->where('long_url_hash', $crc32_hash) + ->where('long_url', $long_url); + } } diff --git a/database/migrations/2017_02_04_025727_add_link_table_indexes.php b/database/migrations/2017_02_04_025727_add_link_table_indexes.php new file mode 100644 index 0000000..8db19b7 --- /dev/null +++ b/database/migrations/2017_02_04_025727_add_link_table_indexes.php @@ -0,0 +1,36 @@ +unique('short_url'); + $table->string('long_url_hash', 10)->nullable(); + $table->index('long_url_hash', 'links_long_url_index'); + }); + + DB::query("UPDATE links SET long_url_hash = crc32(long_url)"); + } + + public function down() + { + Schema::table('links', function (Blueprint $table) + { + $table->longtext('long_url')->change(); + $table->dropUnique('links_short_url_unique'); + $table->dropIndex('links_long_url_index'); + $table->dropColumn('long_url_hash'); + }); + } +} From c228791f952ab5826457f6574db04fc2b85759ce Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Fri, 3 Feb 2017 23:27:54 -0500 Subject: [PATCH 2/7] Add doctrine/dbal dependency, fix raw DB statement to add crc32 hashes to existing links --- composer.json | 3 +- composer.lock | 405 +++++++++++++++++- ...17_02_04_025727_add_link_table_indexes.php | 2 +- 3 files changed, 407 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 01ac744..5c9fcb0 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "paragonie/random_compat": "^1.0.6", "torann/geoip": "^1.0", "geoip2/geoip2": "^2.4", - "nesbot/carbon": "^1.22" + "nesbot/carbon": "^1.22", + "doctrine/dbal": "^2.5" }, "require-dev": { "fzaninotto/faker": "~1.0", diff --git a/composer.lock b/composer.lock index d879a5f..8cd14bb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "5f2914dd5b6b0d6b08ee9051f55ef09f", + "content-hash": "270b76198a63efcbd85347ec35e337f4", "packages": [ { "name": "composer/ca-bundle", @@ -120,6 +120,355 @@ ], "time": "2015-07-23T00:54:12+00:00" }, + { + "name": "doctrine/annotations", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2016-12-30T15:59:45+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-10-29T11:16:17+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-01-03T10:49:41+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "930297026c8009a567ac051fd545bf6124150347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347", + "reference": "930297026c8009a567ac051fd545bf6124150347", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-01-13T14:02:13+00:00" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "fc376f7a61498e18520cd6fa083752a4ca08072b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/fc376f7a61498e18520cd6fa083752a4ca08072b", + "reference": "fc376f7a61498e18520cd6fa083752a4ca08072b", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.8-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*||^3.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2017-01-23T23:17:10+00:00" + }, { "name": "doctrine/inflector", "version": "v1.1.0", @@ -187,6 +536,60 @@ ], "time": "2015-11-06T14:35:42+00:00" }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, { "name": "dompdf/dompdf", "version": "v0.6.2", diff --git a/database/migrations/2017_02_04_025727_add_link_table_indexes.php b/database/migrations/2017_02_04_025727_add_link_table_indexes.php index 8db19b7..db54208 100644 --- a/database/migrations/2017_02_04_025727_add_link_table_indexes.php +++ b/database/migrations/2017_02_04_025727_add_link_table_indexes.php @@ -20,7 +20,7 @@ class AddLinkTableIndexes extends Migration $table->index('long_url_hash', 'links_long_url_index'); }); - DB::query("UPDATE links SET long_url_hash = crc32(long_url)"); + DB::statement("UPDATE links SET long_url_hash = crc32(long_url);"); } public function down() From 358a431ca0807687a9c5226fc3e237d1230f69c0 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Sun, 5 Feb 2017 21:25:52 -0500 Subject: [PATCH 3/7] Remove unnecessary change statement --- database/migrations/2017_02_04_025727_add_link_table_indexes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/database/migrations/2017_02_04_025727_add_link_table_indexes.php b/database/migrations/2017_02_04_025727_add_link_table_indexes.php index db54208..c799a7f 100644 --- a/database/migrations/2017_02_04_025727_add_link_table_indexes.php +++ b/database/migrations/2017_02_04_025727_add_link_table_indexes.php @@ -27,7 +27,6 @@ class AddLinkTableIndexes extends Migration { Schema::table('links', function (Blueprint $table) { - $table->longtext('long_url')->change(); $table->dropUnique('links_short_url_unique'); $table->dropIndex('links_long_url_index'); $table->dropColumn('long_url_hash'); From 38beec6e21aaf581cfd29cf9de0b738dee40fcea Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Tue, 7 Feb 2017 19:50:40 -0500 Subject: [PATCH 4/7] Use an integer field rather than a string field to count clicks, fix #294 --- ...08_003907_alter_link_clicks_to_integer.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 database/migrations/2017_02_08_003907_alter_link_clicks_to_integer.php diff --git a/database/migrations/2017_02_08_003907_alter_link_clicks_to_integer.php b/database/migrations/2017_02_08_003907_alter_link_clicks_to_integer.php new file mode 100644 index 0000000..9879d67 --- /dev/null +++ b/database/migrations/2017_02_08_003907_alter_link_clicks_to_integer.php @@ -0,0 +1,35 @@ +integer('clicks')->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('links', function (Blueprint $table) + { + $table->string('clicks')->change(); + }); + } +} From c4f95cc752c60b72c9136249c9d0514e10988ca7 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Tue, 7 Feb 2017 19:58:17 -0500 Subject: [PATCH 5/7] Add doctrine/dbal dependency for column alterations --- composer.json | 3 +- composer.lock | 405 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 406 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 01ac744..5c9fcb0 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "paragonie/random_compat": "^1.0.6", "torann/geoip": "^1.0", "geoip2/geoip2": "^2.4", - "nesbot/carbon": "^1.22" + "nesbot/carbon": "^1.22", + "doctrine/dbal": "^2.5" }, "require-dev": { "fzaninotto/faker": "~1.0", diff --git a/composer.lock b/composer.lock index d879a5f..232733f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "5f2914dd5b6b0d6b08ee9051f55ef09f", + "content-hash": "270b76198a63efcbd85347ec35e337f4", "packages": [ { "name": "composer/ca-bundle", @@ -120,6 +120,355 @@ ], "time": "2015-07-23T00:54:12+00:00" }, + { + "name": "doctrine/annotations", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2016-12-30T15:59:45+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-10-29T11:16:17+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-01-03T10:49:41+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "930297026c8009a567ac051fd545bf6124150347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347", + "reference": "930297026c8009a567ac051fd545bf6124150347", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-01-13T14:02:13+00:00" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.11", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "1b1effbddbdc0f40d1c8f849f44bcddac4f52a48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/1b1effbddbdc0f40d1c8f849f44bcddac4f52a48", + "reference": "1b1effbddbdc0f40d1c8f849f44bcddac4f52a48", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.8-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*||^3.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2017-02-04T21:20:13+00:00" + }, { "name": "doctrine/inflector", "version": "v1.1.0", @@ -187,6 +536,60 @@ ], "time": "2015-11-06T14:35:42+00:00" }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, { "name": "dompdf/dompdf", "version": "v0.6.2", From 5c2ff762de493132c6f8ce19ec74a8e467895751 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Fri, 10 Feb 2017 16:50:46 -0500 Subject: [PATCH 6/7] Use ORM with chunking to add crc32 hases to old links --- ...2017_02_04_025727_add_link_table_indexes.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/database/migrations/2017_02_04_025727_add_link_table_indexes.php b/database/migrations/2017_02_04_025727_add_link_table_indexes.php index db54208..4b6dc2a 100644 --- a/database/migrations/2017_02_04_025727_add_link_table_indexes.php +++ b/database/migrations/2017_02_04_025727_add_link_table_indexes.php @@ -20,14 +20,27 @@ class AddLinkTableIndexes extends Migration $table->index('long_url_hash', 'links_long_url_index'); }); - DB::statement("UPDATE links SET long_url_hash = crc32(long_url);"); + // MySQL only statement + // DB::statement("UPDATE links SET long_url_hash = crc32(long_url);"); + + DB::table('links')->select(['id', 'long_url_hash', 'long_url']) + ->chunk(100, function($links) { + foreach ($links as $link) { + DB::table('links') + ->where('id', $link->id) + ->update([ + 'long_url_hash' => sprintf('%u', crc32($link->long_url))] + ); + } + }); + + } public function down() { Schema::table('links', function (Blueprint $table) { - $table->longtext('long_url')->change(); $table->dropUnique('links_short_url_unique'); $table->dropIndex('links_long_url_index'); $table->dropColumn('long_url_hash'); From 27cb6ab16a5d007d7594bef62ac5daf9bc3906f5 Mon Sep 17 00:00:00 2001 From: Chaoyi Zha Date: Sat, 11 Feb 2017 10:18:49 -0500 Subject: [PATCH 7/7] Style fix --- .../migrations/2017_02_04_025727_add_link_table_indexes.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/database/migrations/2017_02_04_025727_add_link_table_indexes.php b/database/migrations/2017_02_04_025727_add_link_table_indexes.php index 4b6dc2a..e87d648 100644 --- a/database/migrations/2017_02_04_025727_add_link_table_indexes.php +++ b/database/migrations/2017_02_04_025727_add_link_table_indexes.php @@ -29,12 +29,10 @@ class AddLinkTableIndexes extends Migration DB::table('links') ->where('id', $link->id) ->update([ - 'long_url_hash' => sprintf('%u', crc32($link->long_url))] - ); + 'long_url_hash' => sprintf('%u', crc32($link->long_url)) + ]); } }); - - } public function down()