Upgrade code for new namespaces

This commit is contained in:
Damian Mooyman 2016-07-04 12:44:09 +12:00
parent 85526e7076
commit 946d429c41
11 changed files with 179 additions and 259 deletions

7
.upgrade.yml Normal file
View File

@ -0,0 +1,7 @@
mappings:
PostgreSQLConnector: SilverStripe\PostgreSQL\PostgreSQLConnector
PostgreSQLDatabase: SilverStripe\PostgreSQL\PostgreSQLDatabase
PostgreSQLDatabaseConfigurationHelper: SilverStripe\PostgreSQL\PostgreSQLDatabaseConfigurationHelper
PostgreSQLQuery: SilverStripe\PostgreSQL\PostgreSQLQuery
PostgreSQLQueryBuilder: SilverStripe\PostgreSQL\PostgreSQLQueryBuilder
PostgreSQLSchemaManager: SilverStripe\PostgreSQL\PostgreSQLSchemaManager

View File

@ -1 +0,0 @@
<?php

View File

@ -3,14 +3,21 @@ name: postgresqlconnectors
--- ---
Injector: Injector:
PostgrePDODatabase: PostgrePDODatabase:
class: 'PostgreSQLDatabase' class: 'SilverStripe\PostgreSQL\PostgreSQLDatabase'
properties: properties:
connector: %$PDOConnector connector: %$PDOConnector
schemaManager: %$PostgreSQLSchemaManager schemaManager: %$PostgreSQLSchemaManager
queryBuilder: %$PostgreSQLQueryBuilder queryBuilder: %$PostgreSQLQueryBuilder
PostgreSQLDatabase: PostgreSQLDatabase:
class: 'PostgreSQLDatabase' class: 'SilverStripe\PostgreSQL\PostgreSQLDatabase'
properties: properties:
connector: %$PostgreSQLConnector connector: %$PostgreSQLConnector
schemaManager: %$PostgreSQLSchemaManager schemaManager: %$PostgreSQLSchemaManager
queryBuilder: %$PostgreSQLQueryBuilder queryBuilder: %$PostgreSQLQueryBuilder
PostgreSQLConnector:
class: 'SilverStripe\PostgreSQL\PostgreSQLConnector'
type: prototype
PostgreSQLSchemaManager:
class: 'SilverStripe\PostgreSQL\PostgreSQLSchemaManager'
PostgreSQLQueryBuilder:
class: 'SilverStripe\PostgreSQL\PostgreSQLQueryBuilder'

View File

@ -1,12 +1,17 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use SilverStripe\ORM\Connect\DBConnector;
use ErrorException;
/** /**
* PostgreSQL connector class using the PostgreSQL specific api * PostgreSQL connector class using the PostgreSQL specific api
* *
* The connector doesn't know anything about schema selection, so code related to * The connector doesn't know anything about schema selection, so code related to
* masking multiple databases as schemas should be handled in the database controller * masking multiple databases as schemas should be handled in the database controller
* and schema manager. * and schema manager.
* *
* @package sapphire * @package sapphire
* @subpackage model * @subpackage model
*/ */
@ -14,21 +19,21 @@ class PostgreSQLConnector extends DBConnector
{ {
/** /**
* Connection to the PG Database database * Connection to the PG Database database
* *
* @var resource * @var resource
*/ */
protected $dbConn = null; protected $dbConn = null;
/** /**
* Name of the currently selected database * Name of the currently selected database
* *
* @var string * @var string
*/ */
protected $databaseName = null; protected $databaseName = null;
/** /**
* Reference to the last query result (for pg_affected_rows) * Reference to the last query result (for pg_affected_rows)
* *
* @var resource * @var resource
*/ */
protected $lastQuery = null; protected $lastQuery = null;
@ -44,7 +49,7 @@ class PostgreSQLConnector extends DBConnector
/** /**
* Escape a parameter to be used in the connection string * Escape a parameter to be used in the connection string
* *
* @param array $parameters All parameters * @param array $parameters All parameters
* @param string $key The key in $parameters to pull from * @param string $key The key in $parameters to pull from
* @param string $name The connection string parameter name * @param string $name The connection string parameter name
@ -85,7 +90,7 @@ class PostgreSQLConnector extends DBConnector
if ($this->dbConn) { if ($this->dbConn) {
pg_close($this->dbConn); pg_close($this->dbConn);
} }
// Connect // Connect
$this->dbConn = @pg_connect(implode(' ', $arguments)); $this->dbConn = @pg_connect(implode(' ', $arguments));
if ($this->dbConn === false) { if ($this->dbConn === false) {
@ -143,13 +148,13 @@ class PostgreSQLConnector extends DBConnector
/** /**
* Determines if the SQL fragment either breaks into or out of a string literal * Determines if the SQL fragment either breaks into or out of a string literal
* by counting single quotes * by counting single quotes
* *
* Handles double-quote escaped quotes as well as slash escaped quotes * Handles double-quote escaped quotes as well as slash escaped quotes
* *
* @todo Test this! * @todo Test this!
* *
* @see http://www.postgresql.org/docs/8.3/interactive/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS * @see http://www.postgresql.org/docs/8.3/interactive/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS
* *
* @param string $input The SQL fragment * @param string $input The SQL fragment
* @return boolean True if the string breaks into or out of a string literal * @return boolean True if the string breaks into or out of a string literal
*/ */
@ -167,9 +172,9 @@ class PostgreSQLConnector extends DBConnector
/** /**
* Iteratively replaces all question marks with numerical placeholders * Iteratively replaces all question marks with numerical placeholders
* E.g. "Title = ? AND Name = ?" becomes "Title = $1 AND Name = $2" * E.g. "Title = ? AND Name = ?" becomes "Title = $1 AND Name = $2"
* *
* @todo Better consider question marks in string literals * @todo Better consider question marks in string literals
* *
* @param string $sql Paramaterised query using question mark placeholders * @param string $sql Paramaterised query using question mark placeholders
* @return string Paramaterised query using numeric placeholders * @return string Paramaterised query using numeric placeholders
*/ */
@ -221,13 +226,13 @@ class PostgreSQLConnector extends DBConnector
} else { } else {
$result = pg_query($this->dbConn, $sql); $result = pg_query($this->dbConn, $sql);
} }
// Handle error // Handle error
if ($result === false) { if ($result === false) {
$this->databaseError($this->getLastError(), $errorLevel, $sql, $parameters); $this->databaseError($this->getLastError(), $errorLevel, $sql, $parameters);
return null; return null;
} }
// Save and return results // Save and return results
$this->lastQuery = $result; $this->lastQuery = $result;
$this->lastRows = pg_affected_rows($result); $this->lastRows = pg_affected_rows($result);
@ -253,16 +258,6 @@ class PostgreSQLConnector extends DBConnector
return pg_escape_string($this->dbConn, $value); return pg_escape_string($this->dbConn, $value);
} }
public function escapeIdentifier($value, $separator = '.')
{
if (empty($separator) && function_exists('pg_escape_identifier')) {
return pg_escape_identifier($this->dbConn, $value);
}
// Let parent function handle recursive calls
return parent::escapeIdentifier($value, $separator);
}
public function selectDatabase($name) public function selectDatabase($name)
{ {
if ($name !== $this->databaseName) { if ($name !== $this->databaseName) {

View File

@ -1,8 +1,19 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\Connect\SS_Database;
use Config;
use ErrorException;
use Exception;
use PaginatedList;
/** /**
* PostgreSQL connector class. * PostgreSQL connector class.
* *
* @package sapphire * @package sapphire
* @subpackage model * @subpackage model
*/ */
@ -10,14 +21,14 @@ class PostgreSQLDatabase extends SS_Database
{ {
/** /**
* Database schema manager object * Database schema manager object
* *
* @var PostgreSQLSchemaManager * @var PostgreSQLSchemaManager
*/ */
protected $schemaManager; protected $schemaManager;
/** /**
* The currently selected database schema name. * The currently selected database schema name.
* *
* @var string * @var string
*/ */
protected $schema; protected $schema;
@ -30,22 +41,22 @@ class PostgreSQLDatabase extends SS_Database
/** /**
* Full text cluster method. (e.g. GIN or GiST) * Full text cluster method. (e.g. GIN or GiST)
* *
* @return string * @return string
*/ */
public static function default_fts_cluster_method() public static function default_fts_cluster_method()
{ {
return Config::inst()->get('PostgreSQLDatabase', 'default_fts_cluster_method'); return Config::inst()->get('SilverStripe\\PostgreSQL\\PostgreSQLDatabase', 'default_fts_cluster_method');
} }
/** /**
* Full text search method. * Full text search method.
* *
* @return string * @return string
*/ */
public static function default_fts_search_method() public static function default_fts_search_method()
{ {
return Config::inst()->get('PostgreSQLDatabase', 'default_fts_search_method'); return Config::inst()->get('SilverStripe\\PostgreSQL\\PostgreSQLDatabase', 'default_fts_search_method');
} }
/** /**
@ -55,13 +66,13 @@ class PostgreSQLDatabase extends SS_Database
* Some locked down systems prevent access to the 'postgres' table in * Some locked down systems prevent access to the 'postgres' table in
* which case you need to set this to false. * which case you need to set this to false.
* *
* If allow_query_master_postgres is false, and model_schema_as_database is also false, * If allow_query_master_postgres is false, and model_schema_as_database is also false,
* then attempts to create or check databases beyond the initial connection will * then attempts to create or check databases beyond the initial connection will
* result in a runtime error. * result in a runtime error.
*/ */
public static function allow_query_master_postgres() public static function allow_query_master_postgres()
{ {
return Config::inst()->get('PostgreSQLDatabase', 'allow_query_master_postgres'); return Config::inst()->get('SilverStripe\\PostgreSQL\\PostgreSQLDatabase', 'allow_query_master_postgres');
} }
/** /**
@ -70,13 +81,13 @@ class PostgreSQLDatabase extends SS_Database
* instead of using databases. This may be useful if the database user does not * instead of using databases. This may be useful if the database user does not
* have cross-database permissions, and in cases where multiple databases are used * have cross-database permissions, and in cases where multiple databases are used
* (such as in running test cases). * (such as in running test cases).
* *
* If this is true then the database will only be set during the initial connection, * If this is true then the database will only be set during the initial connection,
* and attempts to change to this database will use the 'public' schema instead * and attempts to change to this database will use the 'public' schema instead
*/ */
public static function model_schema_as_database() public static function model_schema_as_database()
{ {
return Config::inst()->get('PostgreSQLDatabase', 'model_schema_as_database'); return Config::inst()->get('SilverStripe\\PostgreSQL\\PostgreSQLDatabase', 'model_schema_as_database');
} }
/** /**
@ -84,16 +95,16 @@ class PostgreSQLDatabase extends SS_Database
* could be any of the supported languages that can be found in the * could be any of the supported languages that can be found in the
* pg_catalog.pg_ts_config table. * pg_catalog.pg_ts_config table.
* *
* @var string * @return string
*/ */
public static function search_language() public static function search_language()
{ {
return Config::inst()->get('PostgreSQLDatabase', 'search_language'); return Config::inst()->get('SilverStripe\\PostgreSQL\\PostgreSQLDatabase', 'search_language');
} }
/** /**
* The database name specified at initial connection * The database name specified at initial connection
* *
* @var string * @var string
*/ */
protected $databaseOriginal = ''; protected $databaseOriginal = '';
@ -183,7 +194,7 @@ class PostgreSQLDatabase extends SS_Database
/** /**
* Sets the system timezone for the database connection * Sets the system timezone for the database connection
* *
* @param string $timezone * @param string $timezone
*/ */
public function selectTimezone($timezone) public function selectTimezone($timezone)
@ -211,7 +222,7 @@ class PostgreSQLDatabase extends SS_Database
/** /**
* Returns the name of the current schema in use * Returns the name of the current schema in use
* *
* @return string Name of current schema * @return string Name of current schema
*/ */
public function currentSchema() public function currentSchema()
@ -222,8 +233,8 @@ class PostgreSQLDatabase extends SS_Database
/** /**
* Utility method to manually set the schema to an alternative * Utility method to manually set the schema to an alternative
* Check existance & sets search path to the supplied schema name * Check existance & sets search path to the supplied schema name
* *
* @param string $name Name of the schema * @param string $schema Name of the schema
* @param boolean $create Flag indicating whether the schema should be created * @param boolean $create Flag indicating whether the schema should be created
* if it doesn't exist. If $create is false and the schema doesn't exist * if it doesn't exist. If $create is false and the schema doesn't exist
* then an error will be raised * then an error will be raised
@ -256,14 +267,12 @@ class PostgreSQLDatabase extends SS_Database
* the search path is provided as an advanced PostgreSQL feature for raw * the search path is provided as an advanced PostgreSQL feature for raw
* SQL queries. Sapphire cannot search for datamodel tables in alternate * SQL queries. Sapphire cannot search for datamodel tables in alternate
* schemas, so be wary of using alternate schemas within the ORM environment. * schemas, so be wary of using alternate schemas within the ORM environment.
* *
* @param string $arg1 First schema to use * @param string ...$arg Schema name to use. Add additional schema names as extra arguments.
* @param string $arg2 Second schema to use
* @param string $argN Nth schema to use
*/ */
public function setSchemaSearchPath() public function setSchemaSearchPath($arg = null)
{ {
if (func_num_args() == 0) { if (!$arg) {
user_error('At least one Schema must be supplied to set a search path.', E_USER_ERROR); user_error('At least one Schema must be supplied to set a search path.', E_USER_ERROR);
} }
$schemas = array_values(func_get_args()); $schemas = array_values(func_get_args());
@ -274,8 +283,17 @@ class PostgreSQLDatabase extends SS_Database
* The core search engine configuration. * The core search engine configuration.
* @todo Properly extract the search functions out of the core. * @todo Properly extract the search functions out of the core.
* *
* @param array $classesToSearch
* @param string $keywords Keywords as a space separated string * @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 List of result pages
* @throws Exception
*/ */
public function searchEngine($classesToSearch, $keywords, $start, $pageLength, $sortBy = "ts_rank DESC", $extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false) public function searchEngine($classesToSearch, $keywords, $start, $pageLength, $sortBy = "ts_rank DESC", $extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false)
{ {
@ -580,7 +598,7 @@ class PostgreSQLDatabase extends SS_Database
* Determines the name of the current database to be reported externally * Determines the name of the current database to be reported externally
* by substituting the schema name for the database name. * by substituting the schema name for the database name.
* Should only be used when model_schema_as_database is true * Should only be used when model_schema_as_database is true
* *
* @param string $schema Name of the schema * @param string $schema Name of the schema
* @return string Name of the database to report * @return string Name of the database to report
*/ */
@ -595,7 +613,7 @@ class PostgreSQLDatabase extends SS_Database
/** /**
* Translates a requested database name to a schema name to substitute internally. * Translates a requested database name to a schema name to substitute internally.
* Should only be used when model_schema_as_database is true * Should only be used when model_schema_as_database is true
* *
* @param string $database Name of the database * @param string $database Name of the database
* @return string Name of the schema to use for this database internally * @return string Name of the schema to use for this database internally
*/ */
@ -613,7 +631,7 @@ class PostgreSQLDatabase extends SS_Database
// Check current schema is valid // Check current schema is valid
$oldSchema = $this->schema; $oldSchema = $this->schema;
if (empty($oldSchema)) { if (empty($oldSchema)) {
return true; return;
} // Nothing selected to drop } // Nothing selected to drop
// Select another schema // Select another schema
@ -667,6 +685,7 @@ class PostgreSQLDatabase extends SS_Database
// New connection made here, treating the new database name as the new original // New connection made here, treating the new database name as the new original
$this->databaseOriginal = $name; $this->databaseOriginal = $name;
$this->connectDefault(); $this->connectDefault();
return true;
} }
/** /**

View File

@ -1,17 +1,25 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use DatabaseConfigurationHelper;
use PDO;
use Exception;
use DatabaseAdapterRegistry;
/** /**
* This is a helper class for the SS installer. * This is a helper class for the SS installer.
* *
* It does all the specific checking for PostgreSQLDatabase * It does all the specific checking for PostgreSQLDatabase
* to ensure that the configuration is setup correctly. * to ensure that the configuration is setup correctly.
* *
* @package postgresql * @package postgresql
*/ */
class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper
{ {
/** /**
* Create a connection of the appropriate type * Create a connection of the appropriate type
* *
* @param array $databaseConfig * @param array $databaseConfig
* @param string $error Error message passed by value * @param string $error Error message passed by value
* @return mixed|null Either the connection object, or null if error * @return mixed|null Either the connection object, or null if error
@ -22,7 +30,7 @@ class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelp
$username = empty($databaseConfig['username']) ? '' : $databaseConfig['username']; $username = empty($databaseConfig['username']) ? '' : $databaseConfig['username'];
$password = empty($databaseConfig['password']) ? '' : $databaseConfig['password']; $password = empty($databaseConfig['password']) ? '' : $databaseConfig['password'];
$server = $databaseConfig['server']; $server = $databaseConfig['server'];
try { try {
switch ($databaseConfig['type']) { switch ($databaseConfig['type']) {
case 'PostgreSQLDatabase': case 'PostgreSQLDatabase':
@ -95,7 +103,7 @@ class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelp
/** /**
* Ensure that the PostgreSQL version is at least 8.3. * Ensure that the PostgreSQL version is at least 8.3.
* *
* @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc * @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc
* @return array Result - e.g. array('success' => true, 'error' => 'details of error') * @return array Result - e.g. array('success' => true, 'error' => 'details of error')
*/ */
@ -119,28 +127,10 @@ class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelp
'error' => $error 'error' => $error
); );
} }
/**
* Helper function to quote a string value
*
* @param mixed $conn Connection object/resource
* @param string $value Value to quote
* @return string Quoted strieng
*/
protected function quote($conn, $value)
{
if ($conn instanceof PDO) {
return $conn->quote($value);
} elseif (is_resource($conn)) {
return "'".pg_escape_string($conn, $value)."'";
} else {
user_error('Invalid database connection', E_USER_ERROR);
}
}
/** /**
* Helper function to execute a query * Helper function to execute a query
* *
* @param mixed $conn Connection object/resource * @param mixed $conn Connection object/resource
* @param string $sql SQL string to execute * @param string $sql SQL string to execute
* @return array List of first value from each resulting row * @return array List of first value from each resulting row
@ -178,7 +168,7 @@ class PostgreSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelp
$success = in_array($databaseConfig['username'], $allowedUsers); $success = in_array($databaseConfig['username'], $allowedUsers);
} }
} }
return array( return array(
'success' => $success, 'success' => $success,
'alreadyExists' => $alreadyExists 'alreadyExists' => $alreadyExists

View File

@ -1,8 +1,12 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use SilverStripe\ORM\Connect\SS_Query;
/** /**
* A result-set from a PostgreSQL database. * A result-set from a PostgreSQL database.
* *
* @package sapphire * @package sapphire
* @subpackage model * @subpackage model
*/ */
@ -16,8 +20,7 @@ class PostgreSQLQuery extends SS_Query
/** /**
* Hook the result-set given into a Query class, suitable for use by sapphire. * Hook the result-set given into a Query class, suitable for use by sapphire.
* @param database The database object that created this query. * @param resource $handle the internal Postgres handle that is points to the resultset.
* @param handle the internal Postgres handle that is points to the resultset.
*/ */
public function __construct($handle) public function __construct($handle)
{ {

View File

@ -1,5 +1,11 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\Connect\DBQueryBuilder;
use InvalidArgumentException;
class PostgreSQLQueryBuilder extends DBQueryBuilder class PostgreSQLQueryBuilder extends DBQueryBuilder
{ {
/** /**
@ -18,7 +24,7 @@ class PostgreSQLQueryBuilder extends DBQueryBuilder
if (empty($limit)) { if (empty($limit)) {
return ''; return '';
} }
// For literal values return this as the limit SQL // For literal values return this as the limit SQL
if (! is_array($limit)) { if (! is_array($limit)) {
return "{$nl}LIMIT $limit"; return "{$nl}LIMIT $limit";
@ -34,7 +40,7 @@ class PostgreSQLQueryBuilder extends DBQueryBuilder
if ($limit['limit'] === null) { if ($limit['limit'] === null) {
$limit['limit'] = 'ALL'; $limit['limit'] = 'ALL';
} }
$clause = "{$nl}LIMIT {$limit['limit']}"; $clause = "{$nl}LIMIT {$limit['limit']}";
if (isset($limit['start']) && is_numeric($limit['start']) && $limit['start'] !== 0) { if (isset($limit['start']) && is_numeric($limit['start']) && $limit['start'] !== 0) {
$clause .= " OFFSET {$limit['start']}"; $clause .= " OFFSET {$limit['start']}";

View File

@ -1,22 +1,28 @@
<?php <?php
namespace SilverStripe\PostgreSQL;
use SilverStripe\ORM\Connect\DBSchemaManager;
use SilverStripe\ORM\DB;
use Deprecation;
/** /**
* PostgreSQL schema manager * PostgreSQL schema manager
* *
* @package sapphire * @package sapphire
* @subpackage model * @subpackage model
*/ */
class PostgreSQLSchemaManager extends DBSchemaManager class PostgreSQLSchemaManager extends DBSchemaManager
{ {
/** /**
* Identifier for this schema, used for configuring schema-specific table * Identifier for this schema, used for configuring schema-specific table
* creation options * creation options
*/ */
const ID = 'PostgreSQL'; const ID = 'PostgreSQL';
/** /**
* Instance of the database controller this schema belongs to * Instance of the database controller this schema belongs to
* *
* @var PostgreSQLDatabase * @var PostgreSQLDatabase
*/ */
protected $database = null; protected $database = null;
@ -47,7 +53,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Creates a postgres database, ignoring model_schema_as_database * Creates a postgres database, ignoring model_schema_as_database
* *
* @param string $name * @param string $name
*/ */
public function createPostgresDatabase($name) public function createPostgresDatabase($name)
@ -66,7 +72,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Determines if a postgres database exists, ignoring model_schema_as_database * Determines if a postgres database exists, ignoring model_schema_as_database
* *
* @param string $name * @param string $name
* @return boolean * @return boolean
*/ */
@ -87,7 +93,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Determines the list of all postgres databases, ignoring model_schema_as_database * Determines the list of all postgres databases, ignoring model_schema_as_database
* *
* @return array * @return array
*/ */
public function postgresDatabaseList() public function postgresDatabaseList()
@ -109,7 +115,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
} }
/** /**
* Drops a postgres database, ignoring model_schema_as_database * Drops a postgres database, ignoring model_schema_as_database
* *
* @param string $name * @param string $name
*/ */
public function dropPostgresDatabase($name) public function dropPostgresDatabase($name)
@ -122,14 +128,15 @@ class PostgreSQLSchemaManager extends DBSchemaManager
{ {
if (PostgreSQLDatabase::model_schema_as_database()) { if (PostgreSQLDatabase::model_schema_as_database()) {
$schemaName = $this->database->databaseToSchemaName($name); $schemaName = $this->database->databaseToSchemaName($name);
return $this->dropSchema($schemaName); $this->dropSchema($schemaName);
return;
} }
$this->dropPostgresDatabase($name); $this->dropPostgresDatabase($name);
} }
/** /**
* Returns true if the schema exists in the current database * Returns true if the schema exists in the current database
* *
* @param string $name * @param string $name
* @return boolean * @return boolean
*/ */
@ -143,7 +150,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Creates a schema in the current database * Creates a schema in the current database
* *
* @param string $name * @param string $name
*/ */
public function createSchema($name) public function createSchema($name)
@ -154,7 +161,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Drops a schema from the database. Use carefully! * Drops a schema from the database. Use carefully!
* *
* @param string $name * @param string $name
*/ */
public function dropSchema($name) public function dropSchema($name)
@ -165,7 +172,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Returns the list of all available schemas on the current database * Returns the list of all available schemas on the current database
* *
* @return array * @return array
*/ */
public function schemaList() public function schemaList()
@ -257,9 +264,9 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Builds the internal Postgres index name given the silverstripe table and index name * Builds the internal Postgres index name given the silverstripe table and index name
* *
* @param string $tableName * @param string $tableName
* @param string $indexName * @param string $indexName
* @param string $prefix The optional prefix for the index. Defaults to "ix" for indexes. * @param string $prefix The optional prefix for the index. Defaults to "ix" for indexes.
* @return string The postgres name of the index * @return string The postgres name of the index
*/ */
@ -281,7 +288,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Builds the internal Postgres trigger name given the silverstripe table and trigger name * Builds the internal Postgres trigger name given the silverstripe table and trigger name
* *
* @param string $tableName * @param string $tableName
* @param string $triggerName * @param string $triggerName
* @return string The postgres name of the trigger * @return string The postgres name of the trigger
@ -400,7 +407,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
if ($alteredOptions && isset($this->class) && isset($alteredOptions[$this->class])) { if ($alteredOptions && isset($this->class) && isset($alteredOptions[$this->class])) {
$this->query(sprintf("ALTER TABLE \"%s\" %s", $table, $alteredOptions[$this->class])); $this->query(sprintf("ALTER TABLE \"%s\" %s", $table, $alteredOptions[$this->class]));
Database::alteration_message( DB::alteration_message(
sprintf("Table %s options changed: %s", $table, $alteredOptions[$this->class]), sprintf("Table %s options changed: %s", $table, $alteredOptions[$this->class]),
"changed" "changed"
); );
@ -563,7 +570,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Change the database type of the given field. * Change the database type of the given field.
* *
* @param string $tableName The name of the tbale the field is in. * @param string $tableName The name of the tbale the field is in.
* @param string $fieldName The name of the field to change. * @param string $fieldName The name of the field to change.
* @param string $fieldSpec The new field specification * @param string $fieldSpec The new field specification
@ -697,7 +704,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* Create an index on a table. * Create an index on a table.
* *
* @param string $tableName The name of the table. * @param string $tableName The name of the table.
* @param string $indexName The name of the index. * @param string $indexName The name of the index.
* @param string $indexSpec The specification of the index, see Database::requireIndex() for more details. * @param string $indexSpec The specification of the index, see Database::requireIndex() for more details.
@ -773,7 +780,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
//create a type-specific index //create a type-specific index
// NOTE: hash should be removed. This is only here to demonstrate how other indexes can be made // NOTE: hash should be removed. This is only here to demonstrate how other indexes can be made
// NOTE: Quote the index name to preserve case sensitivity // NOTE: Quote the index name to preserve case sensitivity
switch ($indexSpec['type']) { switch ($indexSpec['type']) {
case 'fulltext': case 'fulltext':
// @see fulltext() for the definition of the trigger that ts_$IndexName uses for fulltext searching // @see fulltext() for the definition of the trigger that ts_$IndexName uses for fulltext searching
@ -808,6 +815,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
if ($indexSpec[0] != '(') { if ($indexSpec[0] != '(') {
list($indexType, $indexFields) = explode(' ', $indexSpec, 2); list($indexType, $indexFields) = explode(' ', $indexSpec, 2);
} else { } else {
$indexType = null;
$indexFields = $indexSpec; $indexFields = $indexSpec;
} }
@ -961,7 +969,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/** /**
* A function to return the field names and datatypes for the particular table * A function to return the field names and datatypes for the particular table
* *
* @param string $tableName * @param string $tableName
* @return array List of columns an an associative array with the keys Column and DataType * @return array List of columns an an associative array with the keys Column and DataType
*/ */
@ -1045,28 +1053,12 @@ class PostgreSQLSchemaManager extends DBSchemaManager
* Return a boolean type-formatted string * Return a boolean type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function boolean($values, $asDbValue=false) public function boolean($values)
{ {
//Annoyingly, we need to do a good ol' fashioned switch here:
$default = $values['default'] ? '1' : '0'; $default = $values['default'] ? '1' : '0';
return "smallint default {$default}";
if (!isset($values['arrayValue'])) {
$values['arrayValue']='';
}
if ($asDbValue) {
return array('data_type'=>'smallint');
}
if ($values['arrayValue'] != '') {
$default = '';
} else {
$default = ' default ' . (int)$values['default'];
}
return "smallint{$values['arrayValue']}" . $default;
} }
/** /**
@ -1077,26 +1069,17 @@ class PostgreSQLSchemaManager extends DBSchemaManager
*/ */
public function date($values) public function date($values)
{ {
if (!isset($values['arrayValue'])) { return "date";
$values['arrayValue']='';
}
return "date{$values['arrayValue']}";
} }
/** /**
* Return a decimal type-formatted string * Return a decimal type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function decimal($values, $asDbValue=false) public function decimal($values)
{ {
if (!isset($values['arrayValue'])) {
$values['arrayValue']='';
}
// Avoid empty strings being put in the db // Avoid empty strings being put in the db
if ($values['precision'] == '') { if ($values['precision'] == '') {
$precision = 1; $precision = 1;
@ -1109,11 +1092,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
$defaultValue = ' default ' . floatval($values['default']); $defaultValue = ' default ' . floatval($values['default']);
} }
if ($asDbValue) { return "decimal($precision)$defaultValue";
return array('data_type' => 'numeric', 'precision' => $precision);
} else {
return "decimal($precision){$values['arrayValue']}$defaultValue";
}
} }
/** /**
@ -1124,103 +1103,52 @@ class PostgreSQLSchemaManager extends DBSchemaManager
*/ */
public function enum($values) public function enum($values)
{ {
//Enums are a bit different. We'll be creating a varchar(255) with a constraint of all the usual enum options. $default = " default '{$values['default']}'";
//NOTE: In this one instance, we are including the table name in the values array return "varchar(255)" . $default . " check (\"" . $values['name'] . "\" in ('" . implode('\', \'', $values['enums']) . "'))";
if (!isset($values['arrayValue'])) {
$values['arrayValue']='';
}
if ($values['arrayValue']!='') {
$default = '';
} else {
$default = " default '{$values['default']}'";
}
return "varchar(255){$values['arrayValue']}" . $default . " check (\"" . $values['name'] . "\" in ('" . implode('\', \'', $values['enums']) . "'))";
} }
/** /**
* Return a float type-formatted string * Return a float type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function float($values, $asDbValue = false) public function float($values)
{ {
if (!isset($values['arrayValue'])) { return "float";
$values['arrayValue']='';
}
if ($asDbValue) {
return array('data_type' => 'double precision');
} else {
return "float{$values['arrayValue']}";
}
} }
/** /**
* Return a float type-formatted string cause double is not supported * Return a float type-formatted string cause double is not supported
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function double($values, $asDbValue=false) public function double($values)
{ {
return $this->float($values, $asDbValue); return $this->float($values);
} }
/** /**
* Return a int type-formatted string * Return a int type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function int($values, $asDbValue = false) public function int($values)
{ {
if (!isset($values['arrayValue'])) { return "integer default " . (int)$values['default'];
$values['arrayValue']='';
}
if ($asDbValue) {
return array('data_type'=>'integer', 'precision'=>'32');
}
if ($values['arrayValue']!='') {
$default='';
} else {
$default=' default ' . (int)$values['default'];
}
return "integer{$values['arrayValue']}" . $default;
} }
/** /**
* Return a bigint type-formatted string * Return a bigint type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function bigint($values, $asDbValue = false) public function bigint($values)
{ {
if (!isset($values['arrayValue'])) { return "bigint default" . (int)$values['default'];
$values['arrayValue']='';
}
if ($asDbValue) {
return array('data_type'=>'bigint', 'precision'=>'64');
}
if ($values['arrayValue']!='') {
$default='';
} else {
$default=' default ' . (int)$values['default'];
}
return "bigint{$values['arrayValue']}" . $default;
} }
/** /**
@ -1228,40 +1156,22 @@ class PostgreSQLSchemaManager extends DBSchemaManager
* For PostgreSQL, we simply return the word 'timestamp', no other parameters are necessary * For PostgreSQL, we simply return the word 'timestamp', no other parameters are necessary
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function SS_Datetime($values, $asDbValue = false) public function datetime($values)
{ {
if (!isset($values['arrayValue'])) { return "timestamp";
$values['arrayValue']='';
}
if ($asDbValue) {
return array('data_type'=>'timestamp without time zone');
} else {
return "timestamp{$values['arrayValue']}";
}
} }
/** /**
* Return a text type-formatted string * Return a text type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function text($values, $asDbValue = false) public function text($values)
{ {
if (!isset($values['arrayValue'])) { return "text";
$values['arrayValue'] = '';
}
if ($asDbValue) {
return array('data_type'=>'text');
} else {
return "text{$values['arrayValue']}";
}
} }
/** /**
@ -1272,57 +1182,34 @@ class PostgreSQLSchemaManager extends DBSchemaManager
*/ */
public function time($values) public function time($values)
{ {
if (!isset($values['arrayValue'])) { return "time";
$values['arrayValue'] = '';
}
return "time{$values['arrayValue']}";
} }
/** /**
* Return a varchar type-formatted string * Return a varchar type-formatted string
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function varchar($values, $asDbValue=false) public function varchar($values)
{ {
if (!isset($values['arrayValue'])) {
$values['arrayValue'] = '';
}
if (!isset($values['precision'])) { if (!isset($values['precision'])) {
$values['precision'] = 255; $values['precision'] = 255;
} }
if ($asDbValue) { return "varchar({$values['precision']})";
return array('data_type'=>'varchar', 'precision'=>$values['precision']);
} else {
return "varchar({$values['precision']}){$values['arrayValue']}";
}
} }
/* /*
* Return a 4 digit numeric type. MySQL has a proprietary 'Year' type. * Return a 4 digit numeric type. MySQL has a proprietary 'Year' type.
* For Postgres, we'll use a 4 digit numeric * For Postgres, we'll use a 4 digit numeric
* *
* @param 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
* @param boolean $asDbValue
* @return string * @return string
*/ */
public function year($values, $asDbValue = false) public function year($values)
{ {
if (!isset($values['arrayValue'])) { return "decimal(4,0)";
$values['arrayValue'] = '';
}
//TODO: the DbValue result does not include the numeric_scale option (ie, the ,0 value in 4,0)
if ($asDbValue) {
return array('data_type'=>'decimal', 'precision'=>'4');
} else {
return "decimal(4,0){$values['arrayValue']}";
}
} }
/** /**
@ -1334,7 +1221,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
* @param array $this_index Index specification for the fulltext index * @param array $this_index Index specification for the fulltext index
* @param string $tableName * @param string $tableName
* @param string $name * @param string $name
* @param array $spec * @return array
*/ */
protected function fulltext($this_index, $tableName, $name) protected function fulltext($this_index, $tableName, $name)
{ {
@ -1431,7 +1318,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/* /*
* Given a tablespace and and location, either create a new one * Given a tablespace and and location, either create a new one
* or update the existing one * or update the existing one
* *
* @param string $name * @param string $name
* @param string $location * @param string $location
*/ */
@ -1456,13 +1343,13 @@ class PostgreSQLSchemaManager extends DBSchemaManager
} }
/** /**
* *
* @param string $tableName * @param string $tableName
* @param array $partitions * @param array $partitions
* @param array $indexes * @param array $indexes
* @param array $extensions * @param array $extensions
*/ */
public function createOrReplacePartition($tableName, $partitions, $indexes, $extensions) public function createOrReplacePartition($tableName, $partitions, $indexes = [], $extensions = [])
{ {
//We need the plpgsql language to be installed for this to work: //We need the plpgsql language to be installed for this to work:
@ -1550,7 +1437,7 @@ class PostgreSQLSchemaManager extends DBSchemaManager
/* /*
* This will create a language if it doesn't already exist. * This will create a language if it doesn't already exist.
* This is used by the createOrReplacePartition function, which needs plpgsql * This is used by the createOrReplacePartition function, which needs plpgsql
* *
* @param string $language Language name * @param string $language Language name
*/ */
public function createLanguage($language) public function createLanguage($language)

View File

@ -1,5 +1,7 @@
<?php <?php
use SilverStripe\PostgreSQL\PostgreSQLConnector;
/** /**
* Description of PostgreSQLConnectorTest * Description of PostgreSQLConnectorTest
* *

View File

@ -1,4 +1,9 @@
<?php <?php
use SilverStripe\ORM\DB;
use SilverStripe\ORM\DataObject;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
/** /**
* @package postgresql * @package postgresql
* @subpackage tests * @subpackage tests