Permalink
Browse files

Fixed PEAR sequence table problem in phpws2

phpws2 db worked with PEAR sequence tables, but only if one was
already established. Update creates the table and added the first
id.
  • Loading branch information...
Stardog committed Nov 14, 2017
1 parent 1d653bb commit f99004823e31afe233eb86fd642b6cf94c6e8c56
@@ -9,6 +9,7 @@
*/
class Table extends \phpws2\Database\Table
{
private $storage_engine = 'InnoDB';
/**
@@ -109,7 +110,7 @@ public function getSchemaQuery($column_name = null)
if (isset($column_name)) {
$column = new \phpws2\Variable\Attribute($column_name);
$sql_query.= ' AND information_schema.columns.column_name=\'' .
$sql_query .= ' AND information_schema.columns.column_name=\'' .
$column->get() . '\'';
}
return $sql_query;
@@ -158,10 +159,12 @@ public function getDataType($column_name)
}
$schema = $this->getSchema($column_name);
if (empty($schema)) {
throw new \Exception(sprintf('Unable to retrieve information about column %s', $column_name));
throw new \Exception(sprintf('Unable to retrieve information about column %s',
$column_name));
}
$column_type = $schema['DATA_TYPE'];
$dt = \phpws2\Database\Datatype::factory($this, $column_name, $column_type);
$dt = \phpws2\Database\Datatype::factory($this, $column_name,
$column_type);
$indexes = $this->getIndexes();
if (!empty($indexes)) {
@@ -244,6 +247,15 @@ public function hasPearSequenceTable()
$seq_table_name = $this->getFullName(false) . '_seq';
return $this->db->tableExists($seq_table_name);
}
protected function createPearSequenceTable()
{
$sequence_name = $this->getPearSequenceName();
$query = "CREATE TABLE $sequence_name (id int not null auto_increment, primary key (id))";
$this->db->exec($query);
$this->firstSequenceValue();
}
/**
* Switches from PHPWS_DB's PEAR sequence table dependence to one using
@@ -287,7 +299,8 @@ public function createPrimaryIndexId()
* @param \phpws2\Database\Datatype $old
* @param \phpws2\Database\Datatype $new
*/
public function alter(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype $new)
public function alter(\phpws2\Database\Datatype $old,
\phpws2\Database\Datatype $new)
{
$table_name = $this->getFullName();
$old_column_name = $old->getName();
@@ -9,6 +9,7 @@
*/
class Table extends \phpws2\Database\Table
{
/**
* Table name is NOT included after "using" in a delete query
* @var boolean
@@ -166,7 +167,8 @@ public function getDataType($column_name)
$schema = $this->getSchema($column_name);
$column_type = $schema['data_type'];
$dt = \phpws2\Database\Datatype::factory($this, $column_name, $column_type);
$dt = \phpws2\Database\Datatype::factory($this, $column_name,
$column_type);
$indexes = $this->getIndexes();
if (!empty($indexes)) {
@@ -188,7 +190,8 @@ public function getDataType($column_name)
$dt->setIsNull($schema['is_nullable'] != 'NO');
if ($find_default) {
$default = preg_replace("/::\w[\w\s]+/", '', $schema['column_default']);
$default = preg_replace("/::\w[\w\s]+/", '',
$schema['column_default']);
if (strtolower($default) == 'null') {
$default = null;
@@ -212,13 +215,21 @@ public function hasPearSequenceTable()
return (bool) $result;
}
protected function createPearSequenceTable()
{
$sequence_name = $this->getPearSequenceName();
$query = 'CREATE SEQUENCE $sequence_name INCREMENT 1 START 1';
$this->db->exec($query);
$this->firstSequenceValue();
}
public function getLastPearSequence()
{
$seq_table = $this->getPearSequenceName();
$result = DB::$PDO->query("select nextval('$seq_table')");
return $result->fetchColumn();
}
/**
* Changes id in the Postgresql to serial coupled to its sequence table.
*/
@@ -266,7 +277,8 @@ public function createPrimaryIndexId()
* @param \phpws2\Database\Datatype $old
* @param \phpws2\Database\Datatype $new
*/
public function alter(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype $new)
public function alter(\phpws2\Database\Datatype $old,
\phpws2\Database\Datatype $new)
{
$this->alterColumnParameters($new);
$this->alterNullStatus($old, $new);
@@ -278,7 +290,8 @@ public function alter(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype
* @param \phpws2\Database\Datatype $old
* @param \phpws2\Database\Datatype $new
*/
private function alterNullStatus(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype $new)
private function alterNullStatus(\phpws2\Database\Datatype $old,
\phpws2\Database\Datatype $new)
{
$table_name = $this->getFullName();
$column_name = $new->getName();
@@ -303,7 +316,8 @@ private function alterNullStatus(\phpws2\Database\Datatype $old, \phpws2\Databas
* @param \phpws2\Database\Datatype $old
* @param \phpws2\Database\Datatype $new
*/
private function alterDefaultStatus(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype $new)
private function alterDefaultStatus(\phpws2\Database\Datatype $old,
\phpws2\Database\Datatype $new)
{
$old_default = $old->getDefault();
$new_default = $new->getDefault();
@@ -339,7 +353,7 @@ private function alterColumnParameters(\phpws2\Database\Datatype $new)
EOF;
$this->db->exec($query);
}
public function getPrimaryKeySequenceName()
{
$sql_query = 'SELECT pg_get_serial_sequence(\'' . $this->getFullName(false) . '\', \'id\')';
@@ -23,6 +23,7 @@
*/
abstract class Table extends Resource
{
const default_foreign_key_name = 'default_foreign_key';
/**
@@ -148,7 +149,8 @@
abstract public function constraintTypeAfterName();
abstract public function alter(\phpws2\Database\Datatype $old, \phpws2\Database\Datatype $new);
abstract public function alter(\phpws2\Database\Datatype $old,
\phpws2\Database\Datatype $new);
/**
* Serializes the primary key in the current table. This is a one time method
@@ -169,7 +171,8 @@
* @param \phpws2\Database\Field $field Field to change
* @param string $new_name Name to change field to.
*/
abstract public function renameField(\phpws2\Database\Field $field, $new_name);
abstract public function renameField(\phpws2\Database\Field $field,
$new_name);
/**
* Return the type of database column the current column is.
@@ -219,6 +222,11 @@
abstract public function getPrimaryKeySequenceName();
/**
* Creates a Pear sequence table based of MDB2 query
*/
abstract protected function createPearSequenceTable();
/**
* @param string $name Name of the table
* @param string $alias Alias used in place of table name
@@ -270,10 +278,29 @@ private function checkConstraintTable(Constraint $constraint)
{
$source_table_name = $constraint->getSourceTable()->getFullName();
if ($source_table_name != $this->getFullName()) {
throw new \Exception(sprintf('Source column table %s does not match current table %s', $source_table_name, $this->getFullName()));
throw new \Exception(sprintf('Source column table %s does not match current table %s',
$source_table_name, $this->getFullName()));
}
}
/**
* Gets the max id of a table. Used by createPearSequenceTable
*/
protected function getMaxId()
{
$tableName = $this->getFullName(true);
$pdo = $this->db->query("select max(id) from $tableName");
return $pdo->fetchColumn(0);
}
protected function firstSequenceValue()
{
$sequence_name = $this->getPearSequenceName();
$startId = (int) $this->getMaxId();
$insertQuery = "insert into $sequence_name (id) values ($startId)";
$this->db->exec($insertQuery);
}
/**
* Adds an associative array of values to the table for an update or
* insert execution. If this is a multi-tier array, multiple value
@@ -355,7 +382,8 @@ public function addValue($column, $value = null, $value_key = 0)
public function getValue($column_name, $value = null)
{
if (!$this->db->allowed($column_name)) {
throw new \Exception(sprintf('Improper column name: "%s"', $column_name));
throw new \Exception(sprintf('Improper column name: "%s"',
$column_name));
}
if ($value instanceof \phpws2\Variable) {
$value = $value->toDatabase();
@@ -415,27 +443,32 @@ public function usePearSequence($use = null)
*/
public function insertQuery($use_bind_vars = true)
{
$use_pear = false;
if ($this->hasPearSequenceTable()) {
$use_pear = $this->usePearSequence();
if (is_null($use_pear)) {
throw new \Exception('This table uses a PEAR sequence table. Cannot insert until usePearSequence is set.');
}
if ($this->usePearSequence() && !$this->hasPearSequenceTable()) {
$this->createPearSequenceTable();
}
if (!$this->usePearSequence() && $this->hasPearSequenceTable()) {
throw new \Exception('This table uses a PEAR sequence table. Cannot insert until usePearSequence is set.');
}
$column_values = array();
/**
* If insert select is present, we run with it and stop. The columns are ignored below.
*/
if ($this->insert_select) {
if (empty($this->insert_select_columns)) {
return sprintf('insert into %s %s;', $this->getFullName(), $this->insert_select);
return sprintf('insert into %s %s;', $this->getFullName(),
$this->insert_select);
} else {
return sprintf('insert into %s (%s) %s;', $this->getFullName(), implode(', ', $this->insert_select_columns), $this->insert_select);
return sprintf('insert into %s (%s) %s;', $this->getFullName(),
implode(', ', $this->insert_select_columns),
$this->insert_select);
}
}
if (empty($this->values)) {
throw new \Exception(sprintf(sprintf('No columns to insert in table: %s'), $this->getFullName()));
throw new \Exception(sprintf(sprintf('No columns to insert in table: %s'),
$this->getFullName()));
}
foreach ($this->values as $val_listing) {
$columns = array();
@@ -450,7 +483,8 @@ public function insertQuery($use_bind_vars = true)
# If we are using bind vars, they will be supplied in the DB::insert method
if ($use_bind_vars) {
$column_values = $set_names;
array_walk($column_values, function(&$value) {
array_walk($column_values,
function(&$value) {
$value = ':' . $value;
});
} else {
@@ -465,12 +499,13 @@ public function insertQuery($use_bind_vars = true)
}
reset($this->values);
if ($use_pear) {
if ($this->usePearSequence()) {
$set_names[] = 'id';
$column_values[] = ':id';
}
return sprintf('insert into %s (%s) values (%s);', $this->getFullName(), implode(', ', $set_names), implode(', ', $column_values));
return sprintf('insert into %s (%s) values (%s);', $this->getFullName(),
implode(', ', $set_names), implode(', ', $column_values));
}
/**
@@ -522,7 +557,8 @@ public function setPrimaryKey()
call_user_func_array(array('self', 'setPrimaryKey'), $col);
$recursion = false;
} elseif (is_string($col)) {
$this->primary_key[] = new \phpws2\Database\Field($this, $col, null, false);
$this->primary_key[] = new \phpws2\Database\Field($this, $col,
null, false);
} else {
throw new \Exception('Could not use supplied parameters');
}
@@ -723,7 +759,8 @@ public function getDelimiter()
protected function getConstraintString($create_query = false)
{
foreach ($this->constraints as $c) {
if ($create_query && !is_a($c, '\phpws2\Database\TableCreateConstraint')) {
if ($create_query && !is_a($c,
'\phpws2\Database\TableCreateConstraint')) {
throw new \Exception('This constraint is not allowed during table creation');
}
$sql[] = $c->getConstraintString();
@@ -781,7 +818,12 @@ public function insert()
}
if ($id_column_exists) {
if ($this->usePearSequence()) {
$data['id'] = $this->getLastPearSequence() + 1;
$lastSeq = $this->getLastPearSequence();
if ($lastSeq === false) {
$data['id'] = 1;
} else {
$data['id'] = $lastSeq + 1;
}
}
}
$prep->execute($data);

0 comments on commit f990048

Please sign in to comment.