API Namespace MSSQL connector (#31)

API Update to support customtable names
Update to support new namespaced orm
Cleanup PHPDoc
This commit is contained in:
Damian Mooyman 2016-07-15 13:57:54 +12:00 committed by Sam Minnée
parent 04cf84be71
commit 9309cf3a50
13 changed files with 248 additions and 142 deletions

View File

@ -19,6 +19,7 @@ before_test:
- echo extension=php_curl.dll >> php.ini
- echo extension=php_gd2.dll >> php.ini
- echo extension=php_tidy.dll >> php.ini
- echo extension=php_fileinfo.dll >> php.ini
- php -r "readfile('http://getcomposer.org/installer');" | php
- php -r "readfile('https://dl.dropboxusercontent.com/u/7129062/sqlsrv_unofficial_3.0.2.2.zip');" > sqlsrv.zip
- unzip sqlsrv.zip
@ -40,4 +41,4 @@ test_script:
environment:
DB: MSSQL
CORE_RELEASE: 3
CORE_RELEASE: master

8
.upgrade.yml Normal file
View File

@ -0,0 +1,8 @@
mappings:
MSSQLAzureDatabase: SilverStripe\MSSQL\MSSQLAzureDatabase
MSSQLDatabase: SilverStripe\MSSQL\MSSQLDatabase
MSSQLDatabaseConfigurationHelper: SilverStripe\MSSQL\MSSQLDatabaseConfigurationHelper
MSSQLQueryBuilder: SilverStripe\MSSQL\MSSQLQueryBuilder
MSSQLSchemaManager: SilverStripe\MSSQL\MSSQLSchemaManager
SQLServerConnector: SilverStripe\MSSQL\SQLServerConnector
SQLServerQuery: SilverStripe\MSSQL\SQLServerQuery

View File

@ -4,22 +4,29 @@ name: mssqlconnectors
Injector:
# Connect using PDO
MSSQLPDODatabase:
class: 'MSSQLDatabase'
class: 'SilverStripe\MSSQL\MSSQLDatabase'
properties:
connector: %$PDOConnector
schemaManager: %$MSSQLSchemaManager
queryBuilder: %$MSSQLQueryBuilder
# Uses sqlsrv_connect
MSSQLDatabase:
class: 'MSSQLDatabase'
class: 'SilverStripe\MSSQL\MSSQLDatabase'
properties:
connector: %$SQLServerConnector
schemaManager: %$MSSQLSchemaManager
queryBuilder: %$MSSQLQueryBuilder
# Uses sqlsrv_connect to connect to a MS Azure Database
MSSQLAzureDatabase:
class: 'MSSQLAzureDatabase'
class: 'SilverStripe\MSSQL\MSSQLAzureDatabase'
properties:
connector: %$SQLServerConnector
schemaManager: %$MSSQLSchemaManager
queryBuilder: %$MSSQLQueryBuilder
SQLServerConnector:
class: 'SilverStripe\MSSQL\SQLServerConnector'
type: prototype
MSSQLSchemaManager:
class: 'SilverStripe\MSSQL\MSSQLSchemaManager'
MSSQLQueryBuilder:
class: 'SilverStripe\MSSQL\MSSQLQueryBuilder'

View File

@ -1,6 +1,7 @@
<?php
// PDO connector for MS SQL Server
/** @skipUpgrade */
DatabaseAdapterRegistry::register(array(
'class' => 'MSSQLPDODatabase',
'title' => 'SQL Server 2008 (using PDO)',
@ -13,6 +14,7 @@ DatabaseAdapterRegistry::register(array(
));
// Basic driver using sqlsrv connector
/** @skipUpgrade */
DatabaseAdapterRegistry::register(array(
'class' => 'MSSQLDatabase',
'title' => 'SQL Server 2008 (using sqlsrv)',
@ -31,6 +33,7 @@ DatabaseAdapterRegistry::register(array(
));
// MS Azure uses an online database
/** @skipUpgrade */
DatabaseAdapterRegistry::register(array(
'class' => 'MSSQLAzureDatabase',
'title' => 'MS Azure Database (using sqlsrv)',

View File

@ -1,5 +1,7 @@
<?php
namespace SilverStripe\MSSQL;
/**
* Specific support for SQL Azure databases running on Windows Azure.
* Currently only supports the SQLSRV driver from Microsoft.
@ -47,7 +49,7 @@ class MSSQLAzureDatabase extends MSSQLDatabase
* - database: The database to connect to
* - windowsauthentication: Not supported for Azure
*/
protected function connect($parameters)
public function connect($parameters)
{
$this->parameters = $parameters;
$this->connectDatabase($parameters['database']);
@ -86,9 +88,10 @@ class MSSQLAzureDatabase extends MSSQLDatabase
* database name.
* @see http://msdn.microsoft.com/en-us/library/windowsazure/ee336288.aspx
*
* @param type $name The database name to switch to
* @param type $create
* @param type $errorLevel
* @param string $name The database name to switch to
* @param bool $create
* @param bool|int $errorLevel
* @return bool
*/
public function selectDatabase($name, $create = false, $errorLevel = E_USER_ERROR)
{

View File

@ -1,4 +1,17 @@
<?php
namespace SilverStripe\MSSQL;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Connect\SS_Database;
use Config;
use ClassInfo;
use PaginatedList;
use SilverStripe\ORM\Queries\SQLSelect;
/**
* Microsoft SQL Server 2008+ connector class.
*
@ -72,7 +85,7 @@ class MSSQLDatabase extends SS_Database
*/
public static function set_collation($collation)
{
Config::inst()->update('MSSQLDatabase', 'collation', $collation);
Config::inst()->update('SilverStripe\\MSSQL\\MSSQLDatabase', 'collation', $collation);
}
/**
@ -84,7 +97,7 @@ class MSSQLDatabase extends SS_Database
*/
public static function get_collation()
{
return Config::inst()->get('MSSQLDatabase', 'collation');
return Config::inst()->get('SilverStripe\\MSSQL\\MSSQLDatabase', 'collation');
}
/**
@ -191,9 +204,16 @@ class MSSQLDatabase extends SS_Database
* Picks up the fulltext-indexed tables from the database and executes search on all of them.
* Results are obtained as ID-ClassName pairs which is later used to reconstruct the DataObjectSet.
*
* @param array classesToSearch computes all descendants and includes them. Check is done via WHERE clause.
* @param array $classesToSearch computes all descendants and includes them. Check is done via WHERE clause.
* @param string $keywords Keywords as a space separated string
* @return object DataObjectSet of result pages
* @param int $start
* @param int $pageLength
* @param string $sortBy
* @param string $extraFilter
* @param bool $booleanSearch
* @param string $alternativeFileFilter
* @param bool $invertedMatch
* @return PaginatedList DataObjectSet of result pages
*/
public function searchEngine($classesToSearch, $keywords, $start, $pageLength, $sortBy = "Relevance DESC", $extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false)
{
@ -239,8 +259,7 @@ class MSSQLDatabase extends SS_Database
// Create one query per each table, $columns not used. We want just the ID and the ClassName of the object from this query.
foreach ($tables as $tableName => $columns) {
$baseClass = ClassInfo::baseDataClass($tableName);
$class = DataObject::getSchema()->tableClass($tableName);
$join = $this->fullTextSearchMSSQL($tableName, $keywords);
if (!$join) {
return $results;
@ -248,25 +267,25 @@ class MSSQLDatabase extends SS_Database
// Check if we need to add ShowInSearch
$where = null;
if (strpos($tableName, 'SiteTree') === 0) {
if ($class === 'SiteTree') {
$where = array("\"$tableName\".\"ShowInSearch\"!=0");
} elseif (strpos($tableName, 'File') === 0) {
} elseif ($class === 'File') {
// File.ShowInSearch was added later, keep the database driver backwards compatible
// by checking for its existence first
$fields = $this->fieldList($tableName);
$fields = $this->getSchemaManager()->fieldList($tableName);
if (array_key_exists('ShowInSearch', $fields)) {
$where = array("\"$tableName\".\"ShowInSearch\"!=0");
}
}
$queries[$tableName] = DataList::create($tableName)->where($where, '')->dataQuery()->query();
$queries[$tableName] = DataList::create($class)->where($where)->dataQuery()->query();
$queries[$tableName]->setOrderBy(array());
// Join with CONTAINSTABLE, a full text searcher that includes relevance factor
$queries[$tableName]->setFrom(array("\"$tableName\" INNER JOIN $join AS \"ft\" ON \"$tableName\".\"ID\"=\"ft\".\"KEY\""));
// Join with the base class if needed, as we want to test agains the ClassName
if ($tableName != $baseClass) {
$queries[$tableName]->setFrom("INNER JOIN \"$baseClass\" ON \"$baseClass\".\"ID\"=\"$tableName\".\"ID\"");
if ($tableName != $tableName) {
$queries[$tableName]->setFrom("INNER JOIN \"$tableName\" ON \"$tableName\".\"ID\"=\"$tableName\".\"ID\"");
}
$queries[$tableName]->setSelect(array("\"$tableName\".\"ID\""));
@ -278,7 +297,7 @@ class MSSQLDatabase extends SS_Database
if (count($allClassesToSearch)) {
$classesPlaceholder = DB::placeholders($allClassesToSearch);
$queries[$tableName]->addWhere(array(
"\"$baseClass\".\"ClassName\" IN ($classesPlaceholder)" =>
"\"$tableName\".\"ClassName\" IN ($classesPlaceholder)" =>
$allClassesToSearch
));
}
@ -289,6 +308,7 @@ class MSSQLDatabase extends SS_Database
$querySQLs = array();
$queryParameters = array();
foreach ($queries as $query) {
/** @var SQLSelect $query */
$querySQLs[] = $query->sql($parameters);
$queryParameters = array_merge($queryParameters, $parameters);
}
@ -327,8 +347,8 @@ class MSSQLDatabase extends SS_Database
* Allow auto-increment primary key editing on the given table.
* Some databases need to enable this specially.
*
* @param $table The name of the table to have PK editing allowed on
* @param $allow True to start, false to finish
* @param string $table The name of the table to have PK editing allowed on
* @param bool $allow True to start, false to finish
*/
public function allowPrimaryKeyEditing($table, $allow = true)
{
@ -338,11 +358,10 @@ class MSSQLDatabase extends SS_Database
/**
* Returns a SQL fragment for querying a fulltext search index
*
* @param $tableName specific - table name
* @param $keywords string The search query
* @param $fields array The list of field names to search on, or null to include all
*
* @returns null if keyword set is empty or the string with JOIN clause to be added to SQL query
* @param string $tableName specific - table name
* @param string $keywords The search query
* @param array $fields The list of field names to search on, or null to include all
* @return string Clause, or null if keyword set is empty or the string with JOIN clause to be added to SQL query
*/
public function fullTextSearchMSSQL($tableName, $keywords, $fields = null)
{
@ -429,6 +448,9 @@ class MSSQLDatabase extends SS_Database
/**
* Start transaction. READ ONLY not supported.
*
* @param bool $transactionMode
* @param bool $sessionCharacteristics
*/
public function transactionStart($transactionMode = false, $sessionCharacteristics = false)
{

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\MSSQL;
use DatabaseConfigurationHelper;
use PDO;
use Exception;
use DatabaseAdapterRegistry;
/**
* This is a helper class for the SS installer.
*
@ -13,6 +20,7 @@ class MSSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper
protected function isAzure($databaseConfig)
{
/** @skipUpgrade */
return $databaseConfig['type'] === 'MSSQLAzureDatabase';
}
@ -26,6 +34,7 @@ class MSSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper
protected function createConnection($databaseConfig, &$error)
{
$error = null;
/** @skipUpgrade */
try {
switch ($databaseConfig['type']) {
case 'MSSQLDatabase':
@ -189,6 +198,7 @@ class MSSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper
public function requireDatabaseOrCreatePermissions($databaseConfig)
{
$conn = $this->createConnection($databaseConfig, $error);
/** @skipUpgrade */
if (empty($conn)) {
$success = false;
$alreadyExists = false;

View File

@ -1,5 +1,14 @@
<?php
namespace SilverStripe\MSSQL;
use InvalidArgumentException;
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\Connect\DBQueryBuilder;
/**
* Builds a SQL query string from a SQLExpression object
*

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\MSSQL;
use SilverStripe\ORM\Connect\DBSchemaManager;
/**
* Represents and handles all schema management for a MS SQL database
*
@ -182,13 +189,14 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Create a new table.
* @param $tableName The name of the table
* @param $fields A map of field names to field types
* @param $indexes A map of indexes
* @param $options An map of additional options. The available keys are as follows:
* @param string $tableName The name of the table
* @param array $fields A map of field names to field types
* @param array $indexes A map of indexes
* @param array $options An map of additional options. The available keys are as follows:
* - 'MSSQLDatabase'/'MySQLDatabase'/'PostgreSQLDatabase' - database-specific options such as "engine" for MySQL.
* - 'temporary' - If true, then a temporary table will be created
* @return The table name generated. This may be different from the table name, for example with temporary tables.
* @param array $advancedOptions
* @return string The table name generated. This may be different from the table name, for example with temporary tables.
*/
public function createTable($tableName, $fields = null, $indexes = null, $options = null, $advancedOptions = null)
{
@ -227,18 +235,20 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Alter a table's schema.
* @param $table The name of the table to alter
* @param $newFields New fields, a map of field name => field schema
* @param $newIndexes New indexes, a map of index name => index type
* @param $alteredFields Updated fields, a map of field name => field schema
* @param $alteredIndexes Updated indexes, a map of index name => index type
* @param string $tableName The name of the table to alter
* @param array $newFields New fields, a map of field name => field schema
* @param array $newIndexes New indexes, a map of index name => index type
* @param array $alteredFields Updated fields, a map of field name => field schema
* @param array $alteredIndexes Updated indexes, a map of index name => index type
* @param array $alteredOptions
* @param array $advancedOptions
*/
public function alterTable($tableName, $newFields = null, $newIndexes = null, $alteredFields = null, $alteredIndexes = null, $alteredOptions=null, $advancedOptions=null)
{
$alterList = array();
// drop any fulltext indexes that exist on the table before altering the structure
if ($this->fullTextIndexExists($tableName)) {
if ($this->fulltextIndexExists($tableName)) {
$alterList[] = "\nDROP FULLTEXT INDEX ON \"$tableName\";";
}
@ -712,7 +722,7 @@ class MSSQLSchemaManager extends DBSchemaManager
* Return a boolean type-formatted string
* We use 'bit' so that we can do numeric-based comparisons
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function boolean($values)
@ -724,7 +734,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a date type-formatted string.
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function date($values)
@ -735,7 +745,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a decimal type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function decimal($values)
@ -758,7 +768,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a enum type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function enum($values)
@ -785,7 +795,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a float type-formatted string.
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function float($values)
@ -796,7 +806,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a int type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function int($values)
@ -807,7 +817,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a bigint type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function bigint($values)
@ -819,10 +829,10 @@ class MSSQLSchemaManager extends DBSchemaManager
* Return a datetime type-formatted string
* For MS SQL, we simply return the word 'timestamp', no other parameters are necessary
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function ss_datetime($values)
public function datetime($values)
{
return 'datetime null';
}
@ -830,7 +840,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a text type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function text($values)
@ -843,7 +853,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a time type-formatted string.
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function time($values)
@ -854,7 +864,7 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a varchar type-formatted string
*
* @params array $values Contains a tokenised list of info about this data type
* @param array $values Contains a tokenised list of info about this data type
* @return string
*/
public function varchar($values)
@ -866,6 +876,8 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Return a 4 digit numeric type.
*
* @param array $values
* @return string
*/
public function year($values)
@ -875,6 +887,9 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* This returns the column which is the primary key for each table
*
* @param bool $asDbValue
* @param bool $hasAutoIncPK
* @return string
*/
public function IdColumn($asDbValue = false, $hasAutoIncPK = true)
@ -899,6 +914,10 @@ class MSSQLSchemaManager extends DBSchemaManager
/**
* Returns the values of the given enum field
* NOTE: Experimental; introduced for db-abstraction and may changed before 2.4 is released.
*
* @param string $tableName
* @param string $fieldName
* @return array
*/
public function enumValuesForField($tableName, $fieldName)
{
@ -918,6 +937,9 @@ class MSSQLSchemaManager extends DBSchemaManager
*
* For instance, MSSQL uses 'BIGINT', while MySQL uses 'UNSIGNED'
* and PostgreSQL uses 'INT'.
*
* @param string $type
* @return string
*/
public function dbDataType($type)
{

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\MSSQL;
use SilverStripe\ORM\Connect\DBConnector;
/**
* Database connector driver for sqlsrv_ library
*
@ -195,7 +202,7 @@ class SQLServerConnector extends DBConnector
* Quotes a string, including the "N" prefix so unicode
* strings are saved to the database correctly.
*
* @param string $string String to be encoded
* @param string $value String to be encoded
* @return string Processed string ready for DB
*/
public function quoteString($value)

View File

@ -1,5 +1,12 @@
<?php
namespace SilverStripe\MSSQL;
use SilverStripe\ORM\Connect\SS_Query;
use DateTime;
/**
* A result-set from a MSSQL database.
*

View File

@ -14,11 +14,16 @@
}
],
"require": {
"silverstripe/framework": ">=3.2"
"silverstripe/framework": "^4"
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"SilverStripe\\MSSQL\\": "code/"
}
},
"prefer-stable": true,

View File

@ -1,4 +1,6 @@
<?php
use SilverStripe\ORM\DataObject;
class MSSQLDatabaseQueryTest extends SapphireTest
{
@ -23,8 +25,8 @@ class MSSQLDatabaseQueryTest extends SapphireTest
class MSSQLDatabaseQueryTestDataObject extends DataObject implements TestOnly
{
public static $db = array(
private static $db = array(
'TestDate' => 'Date',
'TestDatetime' => 'SS_Datetime'
'TestDatetime' => 'Datetime'
);
}