mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
pkrenn: Issues with prepared statements fixed (as they are limited to only a few positions).
fieldList() is nearly finished, only the default values are not working correctly, but that should be done rather soon (merged from branches/gsoc) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@41710 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
9a516662d0
commit
c892ad24a3
@ -119,9 +119,9 @@ class PDODatabase extends Database {
|
|||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getVersion() {
|
public function getVersion() {
|
||||||
switch ($type) {
|
switch (PDO::ATTR_DRIVER_NAME) {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
case "postgresql":
|
case "pgsql":
|
||||||
$query = "SELECT VERSION()";
|
$query = "SELECT VERSION()";
|
||||||
break;
|
break;
|
||||||
case "mssql":
|
case "mssql":
|
||||||
@ -173,8 +173,7 @@ class PDODatabase extends Database {
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getGeneratedID($table) {
|
public function getGeneratedID($table) {
|
||||||
$stmt = $dbConn->prepare("SELECT MAX(ID) FROM :table");
|
$stmt = $dbConn->prepare("SELECT MAX(ID) FROM $table");
|
||||||
$stmt->bindParam(":table", $table);
|
|
||||||
$handle = $stmt->execute();
|
$handle = $stmt->execute();
|
||||||
$result = $stmt->fetchColumn();
|
$result = $stmt->fetchColumn();
|
||||||
return $handle ? $result : 0;
|
return $handle ? $result : 0;
|
||||||
@ -188,8 +187,7 @@ class PDODatabase extends Database {
|
|||||||
*/
|
*/
|
||||||
public function getNextID($table) {
|
public function getNextID($table) {
|
||||||
user_error('getNextID is OBSOLETE (and will no longer work properly)', E_USER_WARNING);
|
user_error('getNextID is OBSOLETE (and will no longer work properly)', E_USER_WARNING);
|
||||||
$stmt = $dbConn->prepare("SELECT MAX(ID)+1 FROM :table");
|
$stmt = $dbConn->prepare("SELECT MAX(ID)+1 FROM $table");
|
||||||
$stmt->bindParam(":table", $table);
|
|
||||||
$handle = $stmt->execute();
|
$handle = $stmt->execute();
|
||||||
$result = $stmt->fetchColumn();
|
$result = $stmt->fetchColumn();
|
||||||
return $handle ? $result : 1;
|
return $handle ? $result : 1;
|
||||||
@ -216,8 +214,7 @@ class PDODatabase extends Database {
|
|||||||
public function createDatabase($connect, $username, $password, $database) {
|
public function createDatabase($connect, $username, $password, $database) {
|
||||||
try {
|
try {
|
||||||
$dbConn = new PDO($connect, $username, $password);
|
$dbConn = new PDO($connect, $username, $password);
|
||||||
$stmt = $dbConn->prepare("CREATE DATABASE :database");
|
$stmt = $dbConn->prepare("CREATE DATABASE $database");
|
||||||
$stmt->bindParam(":database", $database);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$this->active = true;
|
$this->active = true;
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
@ -238,19 +235,20 @@ class PDODatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch ($parameters['type']) {
|
switch ($parameters['type']) {
|
||||||
|
|
||||||
|
switch (PDO::ATTR_DRIVER_NAME) {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
$stmt = $dbConn->prepare("CREATE TABLE :tableName (ID INT(11) NOT NULL AUTO_INCREMENT, $fieldSchemas PRIMARY KEY (ID)) TYPE=MyISAM");
|
$stmt = $dbConn->prepare("CREATE TABLE $tableName (ID INT(11) NOT NULL AUTO_INCREMENT, $fieldSchemas PRIMARY KEY (ID)) TYPE=MyISAM");
|
||||||
break;
|
break;
|
||||||
case "postgresql":
|
case "pgsql":
|
||||||
$stmt = $dbConn->prepare("CREATE TABLE :tableName (ID SERIAL, $fieldSchemas PRIMARY KEY (ID))");
|
$stmt = $dbConn->prepare("CREATE TABLE $tableName (ID SERIAL, $fieldSchemas PRIMARY KEY (ID))");
|
||||||
break;
|
break;
|
||||||
case "mssql":
|
case "mssql":
|
||||||
$stmt = $dbConn->prepare("CREATE TABLE :tableName (ID INT(11) IDENTITY(1,1), $fieldSchemas PRIMARY KEY (ID))");
|
$stmt = $dbConn->prepare("CREATE TABLE $tableName (ID INT(11) IDENTITY(1,1), $fieldSchemas PRIMARY KEY (ID))");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->databaseError("This database server is not available");
|
$this->databaseError("This database server is not available");
|
||||||
}
|
}
|
||||||
$stmt->bindParam(":tableName", $tableName);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
if ($indexes) {
|
if ($indexes) {
|
||||||
@ -270,72 +268,29 @@ class PDODatabase extends Database {
|
|||||||
public function alterTable($table, $newFields, $newIndexes, $alteredFields, $alteredIndexes) {
|
public function alterTable($table, $newFields, $newIndexes, $alteredFields, $alteredIndexes) {
|
||||||
|
|
||||||
if ($newFields) {
|
if ($newFields) {
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :table ADD :field :type");
|
foreach ($newFields as $field => $type) {
|
||||||
$stmt->bindParam(':table', $table);
|
$stmt = $dbConn->prepare("ALTER TABLE $table ADD $field $type");
|
||||||
$stmt->bindParam(':field', $field);
|
|
||||||
$stmt->bindParam(':type', $type);
|
|
||||||
foreach ($newFields as $k => $v) {
|
|
||||||
$field = $k;
|
|
||||||
$type = $v;
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($newIndexes) {
|
if ($newIndexes) {
|
||||||
$stmt = $dbConn->prepare("CREATE INDEX :name ON :table :column");
|
foreach ($newIndexes as $name => $column) {
|
||||||
$stmt->bindParam(':table', $table);
|
$stmt = $dbConn->prepare("CREATE INDEX $name ON $table $column");
|
||||||
$stmt->bindParam(':name', $name);
|
|
||||||
$stmt->bindParam(':column', $column);
|
|
||||||
foreach ($newIndexes as $k => $v) {
|
|
||||||
$name = $k;
|
|
||||||
$column = $v;
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($alteredFields) {
|
if ($alteredFields) {
|
||||||
switch ($parameters['type']) {
|
foreach ($alteredFields as $field => $type) {
|
||||||
case "mysql":
|
alterField($table, $field, $type)
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :table CHANGE :field :field :type");
|
|
||||||
break;
|
|
||||||
case "postgresql":
|
|
||||||
$stmt = $dbConn->prepare("
|
|
||||||
BEGIN;
|
|
||||||
ALTER TABLE :table RENAME :field TO oldfield;
|
|
||||||
ALTER TABLE :table ADD COLUMN :field :type;
|
|
||||||
UPDATE :table SET :field = CAST(oldfield AS :type);
|
|
||||||
ALTER TABLE :table DROP COLUMN oldfield;
|
|
||||||
COMMIT;
|
|
||||||
");
|
|
||||||
break;
|
|
||||||
case "mssql":
|
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :table ALTER COLUMN :field :type");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->databaseError("This database server is not available");
|
|
||||||
}
|
|
||||||
$stmt->bindParam(':table', $table);
|
|
||||||
$stmt->bindParam(':field', $field);
|
|
||||||
$stmt->bindParam(':type', $type);
|
|
||||||
foreach ($alteredFields as $k => $v) {
|
|
||||||
$field = $k;
|
|
||||||
$type = $v;
|
|
||||||
$stmt->execute();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($alteredIndexes) {
|
if ($alteredIndexes) {
|
||||||
$drop = $dbConn->prepare("DROP INDEX :drop");
|
foreach ($newIndexes as $name => $column) {
|
||||||
$drop->bindParam(':drop', $drop);
|
$dbConn->query("DROP INDEX $name");
|
||||||
$stmt = $dbConn->prepare("CREATE INDEX :name ON :table :column");
|
$stmt = $dbConn->prepare("CREATE INDEX $name ON $table $column");
|
||||||
$stmt->bindParam(':table', $table);
|
|
||||||
$stmt->bindParam(':name', $name);
|
|
||||||
$stmt->bindParam(':column', $column);
|
|
||||||
foreach ($newIndexes as $k => $v) {
|
|
||||||
$drop = $k;
|
|
||||||
$drop->execute();
|
|
||||||
$name = $k;
|
|
||||||
$column = $v;
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,9 +303,7 @@ class PDODatabase extends Database {
|
|||||||
* @return void.
|
* @return void.
|
||||||
*/
|
*/
|
||||||
public function renameTable($oldTableName, $newTableName) {
|
public function renameTable($oldTableName, $newTableName) {
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :oldTableName RENAME TO :newTableName");
|
$stmt = $dbConn->prepare("ALTER TABLE $oldTableName RENAME TO $newTableName");
|
||||||
$stmt->bindParam(":oldTableName", $oldTableName);
|
|
||||||
$stmt->bindParam(":newTableName", $newTableName);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,10 +350,7 @@ class PDODatabase extends Database {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function createField($tableName, $fieldName, $fieldSpec) {
|
public function createField($tableName, $fieldName, $fieldSpec) {
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :tableName ADD :fieldName :fieldSpec");
|
$stmt = $dbConn->prepare("ALTER TABLE $tableName ADD $fieldName $fieldSpec");
|
||||||
$stmt->bindParam(":tableName", $tableName);
|
|
||||||
$stmt->bindParam(":fieldName", $fieldName);
|
|
||||||
$stmt->bindParam(":fieldSpec", $fieldSpec);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,29 +362,26 @@ class PDODatabase extends Database {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function alterField($table, $field, $type) {
|
public function alterField($table, $field, $type) {
|
||||||
switch ($parameters['type']) {
|
switch (PDO::ATTR_DRIVER_NAME) {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :table CHANGE :field :field :type");
|
$stmt = $dbConn->prepare("ALTER TABLE $table CHANGE $field $field $type");
|
||||||
break;
|
break;
|
||||||
case "postgresql":
|
case "pgsql":
|
||||||
$stmt = $dbConn->prepare("
|
$stmt = $dbConn->prepare("
|
||||||
BEGIN;
|
BEGIN;
|
||||||
ALTER TABLE :table RENAME :field TO oldfield;
|
ALTER TABLE $table RENAME $field TO oldfield;
|
||||||
ALTER TABLE :table ADD COLUMN :field :type;
|
ALTER TABLE $table ADD COLUMN $field $type;
|
||||||
UPDATE :table SET :field = CAST(oldfield AS :type);
|
UPDATE $table SET $field = CAST(oldfield AS $type);
|
||||||
ALTER TABLE :table DROP COLUMN oldfield;
|
ALTER TABLE $table DROP COLUMN oldfield;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
");
|
");
|
||||||
break;
|
break;
|
||||||
case "mssql":
|
case "mssql":
|
||||||
$stmt = $dbConn->prepare("ALTER TABLE :table ALTER COLUMN :field :type");
|
$stmt = $dbConn->prepare("ALTER TABLE $table ALTER COLUMN $field $type");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->databaseError("This database server is not available");
|
$this->databaseError("This database server is not available");
|
||||||
}
|
}
|
||||||
$stmt->bindParam(':table', $table);
|
|
||||||
$stmt->bindParam(':field', $field);
|
|
||||||
$stmt->bindParam(':type', $type);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,10 +393,7 @@ class PDODatabase extends Database {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function createIndex($tableName, $indexName, $indexSpec) {
|
public function createIndex($tableName, $indexName, $indexSpec) {
|
||||||
$stmt = $dbConn->prepare("CREATE INDEX :name ON :table :column");
|
$stmt = $dbConn->prepare("CREATE INDEX $indexName ON $tableName $indexSpec");
|
||||||
$stmt->bindParam(':table', $tableName);
|
|
||||||
$stmt->bindParam(':name', $indexName);
|
|
||||||
$stmt->bindParam(':column', $indexSpec);
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,25 +405,101 @@ class PDODatabase extends Database {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function alterIndex($tableName, $indexName, $indexSpec) {
|
public function alterIndex($tableName, $indexName, $indexSpec) {
|
||||||
$drop = $dbConn->prepare("DROP INDEX :drop");
|
$dbConn->query("DROP INDEX $indexName");
|
||||||
$drop->bindParam(':drop', $indexName);
|
$stmt = $dbConn->prepare("CREATE INDEX $indexName ON $tableName $indexSpec");
|
||||||
$stmt = $dbConn->prepare("CREATE INDEX :name ON :table :column");
|
|
||||||
$stmt->bindParam(':table', $tableName);
|
|
||||||
$stmt->bindParam(':name', $indexName);
|
|
||||||
$stmt->bindParam(':column', $indexSpec);
|
|
||||||
$drop->execute();
|
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of all the fields for the given table.
|
* Get a list of all the fields for the given table.
|
||||||
|
* The results are not totally equal for all databases (for example collations are handled very differently, PostgreSQL disregards zerofill,...)
|
||||||
|
* but as close as possible and necessary.
|
||||||
* @param string $able Table of which to show the fields.
|
* @param string $able Table of which to show the fields.
|
||||||
* Returns a map of field name => field spec.
|
* Returns a map of field name => field spec.
|
||||||
*/
|
*/
|
||||||
public function fieldList($table) {
|
public function fieldList($table) {
|
||||||
|
switch (PDO::ATTR_DRIVER_NAME) {
|
||||||
|
case "mysql":
|
||||||
|
foreach ($dbConn->query("SHOW FULL FIELDS IN $table") as $field) {
|
||||||
|
$fieldSpec = $field['Type'];
|
||||||
|
if(!$field['Null'] || $field['Null'] == 'NO') {
|
||||||
|
$fieldSpec .= ' not null';
|
||||||
|
}
|
||||||
|
if($field['Collation'] && $field['Collation'] != 'NULL') {
|
||||||
|
$values = $dbh->prepare("SHOW COLLATION LIKE '$field[Collation]'");
|
||||||
|
$values->execute();
|
||||||
|
$collInfo = $values->fetchColumn();
|
||||||
|
$fieldSpec .= " character set $collInfo[Charset] collate $field[Collation]";
|
||||||
|
}
|
||||||
|
if($field['Default'] || $field['Default'] === "0") {
|
||||||
|
$fieldSpec .= " default '" . addslashes($field['Default']) . "'";
|
||||||
|
}
|
||||||
|
if($field['Extra']) $fieldSpec .= " $field[Extra]";
|
||||||
|
$fieldList[$field['Field']] = $fieldSpec;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "pgsql":
|
||||||
|
foreach ($dbh->query("
|
||||||
|
SELECT
|
||||||
|
a.attname AS field,
|
||||||
|
pg_catalog.format_type(a.atttypid, a.atttypmod) AS type,
|
||||||
|
a.attnotnull AS null
|
||||||
|
FROM
|
||||||
|
pg_class c,
|
||||||
|
pg_attribute a,
|
||||||
|
pg_type t
|
||||||
|
WHERE
|
||||||
|
c.relname = $table
|
||||||
|
AND a.attnum > 0
|
||||||
|
AND a.attrelid = c.oid
|
||||||
|
AND a.atttypid = t.oid
|
||||||
|
AND (NOT A.attisdropped)
|
||||||
|
ORDER BY
|
||||||
|
a.attnum
|
||||||
|
") as $field) {
|
||||||
|
$fieldSpec = $field['type'];
|
||||||
|
if ($field['null'] == 't') {
|
||||||
|
$fieldSpec .= ' not null';
|
||||||
|
}
|
||||||
|
|
||||||
// to be done - SHOW is used extensively but very MySQL specific
|
$fieldList[$field['field']] = $fieldSpec;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "mssql":
|
||||||
|
foreach ($dbh->query("
|
||||||
|
SELECT
|
||||||
|
COLUMN_NAME as 'field',
|
||||||
|
COLUMN_DEFAULT as 'default',
|
||||||
|
IS_NULLABLE as 'null',
|
||||||
|
DATA_TYPE as 'type',
|
||||||
|
COLLATION_NAME as 'collation',
|
||||||
|
CHARACTER_SET_NAME as 'characterset'
|
||||||
|
FROM
|
||||||
|
information_schema.columns
|
||||||
|
WHERE
|
||||||
|
TABLE_NAME = 'tableb'
|
||||||
|
") as $field) {
|
||||||
|
$fieldSpec = $field['type'];
|
||||||
|
if ($field['null'] == 't') {
|
||||||
|
$fieldSpec .= ' not null';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($field['collation'] && $field['collation'] != 'NULL') {
|
||||||
|
$fieldSpec .= " character set $field[characterset] collate $field[collation]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($field['default'] || $field['default'] === "0") {
|
||||||
|
$fieldSpec .= " default '" . addslashes($field['default']) . "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$fieldList[$field['field']] = $fieldSpec;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->databaseError("This database server is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fieldList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -499,11 +519,11 @@ class PDODatabase extends Database {
|
|||||||
* Returns a map of a table.
|
* Returns a map of a table.
|
||||||
*/
|
*/
|
||||||
public function tableList() {
|
public function tableList() {
|
||||||
switch ($parameters['type']) {
|
switch (PDO::ATTR_DRIVER_NAME) {
|
||||||
case "mysql":
|
case "mysql":
|
||||||
$sql = "SHOW TABLES";
|
$sql = "SHOW TABLES";
|
||||||
break;
|
break;
|
||||||
case "postgresql":
|
case "pgsql":
|
||||||
$sql = "SELECT tablename FROM pg_tables WHERE tablename NOT ILIKE 'pg_%' AND tablename NOT ILIKE 'sql_%'";
|
$sql = "SELECT tablename FROM pg_tables WHERE tablename NOT ILIKE 'pg_%' AND tablename NOT ILIKE 'sql_%'";
|
||||||
break;
|
break;
|
||||||
case "mssql":
|
case "mssql":
|
||||||
|
Loading…
Reference in New Issue
Block a user