From 2717f013447069fd1879b24140dd84145ece9cef Mon Sep 17 00:00:00 2001 From: JorisDebonnet Date: Wed, 29 Nov 2017 21:31:56 +0100 Subject: [PATCH 1/3] Fix link to nginx.org wiki --- .../01_Installation/How_To/Configure_Nginx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md index a8ae1cbd3..a079b03ad 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md @@ -1,7 +1,7 @@ # Nginx These instructions are also covered on the -[Nginx Wiki](http://wiki.nginx.org/SilverStripe). +[Nginx Wiki](https://www.nginx.com/resources/wiki/start/topics/recipes/silverstripe/). The prerequisite is that you have already installed Nginx and you are able to run PHP files via the FastCGI-wrapper from Nginx. From 2e43780a8ae664ead109bd99c094f3873defbfea Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Mon, 6 Nov 2017 14:40:50 +0000 Subject: [PATCH 2/3] NEW Add sort columns to DB index automatically --- .../00_Model/12_Indexes.md | 3 ++ model/DataObject.php | 24 ++++++++++ .../model/DataObjectSchemaGenerationTest.php | 48 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/docs/en/02_Developer_Guides/00_Model/12_Indexes.md b/docs/en/02_Developer_Guides/00_Model/12_Indexes.md index a3e2c2e72..3366d5804 100644 --- a/docs/en/02_Developer_Guides/00_Model/12_Indexes.md +++ b/docs/en/02_Developer_Guides/00_Model/12_Indexes.md @@ -50,6 +50,9 @@ In order to use more database specific or complex index notations, we also suppo ); } +As of 3.7.0 `default_sort` fields will automatically become database indexes as this provides significant performance +benefits. + ## API Documentation * [api:DataObject] diff --git a/model/DataObject.php b/model/DataObject.php index 6c578bd1f..d8498e565 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -3387,6 +3387,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity public function databaseIndexes() { $has_one = $this->uninherited('has_one',true); $classIndexes = $this->uninherited('indexes',true); + $sort = $this->uninherited('default_sort',true); //$fileIndexes = $this->uninherited('fileIndexes', true); $indexes = array(); @@ -3403,6 +3404,29 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } } + if ($sort && is_string($sort)) { + $sort = preg_split('/,(?![^()]*+\\))/', $sort); + + foreach ($sort as $value) { + $value = trim($value); + if(strpos($value, ' ') !== false) { + $parts = explode(' ', $value, 2); + $column = $parts[0]; + } else { + $column = $value; + } + if (substr($column, 0, 1) === '"') { + $column = substr($column, 1, strlen($column)-1); + } + if (substr($column, -1, 1) === '"') { + $column = substr($column, 0, -1); + } + if ($this->hasOwnTableDatabaseField($column) && !array_key_exists($column, $indexes)) { + $indexes[$column] = true; + } + } + } + if(get_parent_class($this) == "DataObject") { $indexes['ClassName'] = true; } diff --git a/tests/model/DataObjectSchemaGenerationTest.php b/tests/model/DataObjectSchemaGenerationTest.php index 505cf6624..80f590210 100644 --- a/tests/model/DataObjectSchemaGenerationTest.php +++ b/tests/model/DataObjectSchemaGenerationTest.php @@ -172,6 +172,45 @@ class DataObjectSchemaGenerationTest extends SapphireTest { $item1->delete(); $item2->delete(); } + + public function testSortFieldBecomeIndexes() + { + $object = new DataObjectSchemaGenerationTest_Sorted(); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', 'Sort ASC'); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', 'Sort DESC'); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', '"Sort" DESC'); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', '"Sort" DESC, "Title" ASC'); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + $this->assertArrayHasKey('Title', $indexes); + $this->assertTrue($indexes['Title']); + + // make sure that specific indexes aren't overwritten + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'indexes', array( + 'Sort' => 'unique', + )); + + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertEquals('unique', $indexes['Sort']); + } } class DataObjectSchemaGenerationTest_DO extends DataObject implements TestOnly { @@ -212,3 +251,12 @@ class DataObjectSchemaGenerationTest_IndexDO extends DataObjectSchemaGenerationT 'SearchFields' => 'fulltext ("Title","Content")' ); } + +class DataObjectSchemaGenerationTest_Sorted extends DataObject implements TestOnly { + private static $db = array( + 'Title' => 'Varchar', + 'Sort' => 'Int', + ); + + private static $default_sort = "Sort"; +} \ No newline at end of file From 89166a2ff2e174de81592fb19e0ba40117223809 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Tue, 5 Dec 2017 14:43:21 +0000 Subject: [PATCH 3/3] Try using parseSortColumn from ArrayList --- model/ArrayList.php | 4 +- model/DataObject.php | 51 ++++++++++++------- .../model/DataObjectSchemaGenerationTest.php | 6 +++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/model/ArrayList.php b/model/ArrayList.php index b15e3b04c..8b6b07bcb 100644 --- a/model/ArrayList.php +++ b/model/ArrayList.php @@ -348,8 +348,8 @@ class ArrayList extends ViewableData implements SS_List, SS_Filterable, SS_Sorta /** * Parses a specified column into a sort field and direction * - * @param type $column String to parse containing the column name - * @param type $direction Optional Additional argument which may contain the direction + * @param string $column String to parse containing the column name + * @param string $direction Optional Additional argument which may contain the direction * @return array Sort specification in the form array("Column", SORT_ASC). */ protected function parseSortColumn($column, $direction = null) { diff --git a/model/DataObject.php b/model/DataObject.php index d8498e565..ae4958ea9 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -3405,25 +3405,23 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } if ($sort && is_string($sort)) { - $sort = preg_split('/,(?![^()]*+\\))/', $sort); + $sort = preg_split('/,(?![^()]*+\\))/', $sort); foreach ($sort as $value) { - $value = trim($value); - if(strpos($value, ' ') !== false) { - $parts = explode(' ', $value, 2); - $column = $parts[0]; - } else { - $column = $value; - } - if (substr($column, 0, 1) === '"') { - $column = substr($column, 1, strlen($column)-1); - } - if (substr($column, -1, 1) === '"') { - $column = substr($column, 0, -1); - } - if ($this->hasOwnTableDatabaseField($column) && !array_key_exists($column, $indexes)) { - $indexes[$column] = true; - } + try { + list ($table, $column) = $this->parseSortColumn(trim($value)); + + $table = trim($table, '"'); + $column = trim($column, '"'); + + if ($table && strtolower($table) !== strtolower($this->class)) { + continue; + } + + if ($this->hasOwnTableDatabaseField($column) && !array_key_exists($column, $indexes)) { + $indexes[$column] = true; + } + } catch (InvalidArgumentException $e) { } } } @@ -3434,6 +3432,25 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity return $indexes; } + /** + * Parses a specified column into a sort field and direction + * + * @param string $column String to parse containing the column name + * @return array Resolved table and column. + */ + protected function parseSortColumn($column) { + // Parse column specification, considering possible ansi sql quoting + // Note that table prefix is allowed, but discarded + if(preg_match('/^("?(?[^"\s]+)"?\\.)?"?(?[^"\s]+)"?(\s+(?((asc)|(desc))(ending)?))?$/i', $column, $match)) { + $table = $match['table']; + $column = $match['column']; + } else { + throw new InvalidArgumentException("Invalid sort() column"); + } + + return array($table, $column); + } + /** * Check the database schema and update it as necessary. * diff --git a/tests/model/DataObjectSchemaGenerationTest.php b/tests/model/DataObjectSchemaGenerationTest.php index 80f590210..2641c2268 100644 --- a/tests/model/DataObjectSchemaGenerationTest.php +++ b/tests/model/DataObjectSchemaGenerationTest.php @@ -195,6 +195,12 @@ class DataObjectSchemaGenerationTest extends SapphireTest { $this->assertArrayHasKey('Sort', $indexes); $this->assertTrue($indexes['Sort']); + + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', '"DataObjectSchemaGenerationTest_Sorted"."Sort" ASC'); + $indexes = $object->databaseIndexes(); + $this->assertArrayHasKey('Sort', $indexes); + $this->assertTrue($indexes['Sort']); + Config::inst()->update('DataObjectSchemaGenerationTest_Sorted', 'default_sort', '"Sort" DESC, "Title" ASC'); $indexes = $object->databaseIndexes(); $this->assertArrayHasKey('Sort', $indexes);