public function beforeCall($proxied, $method, $args, &$alternateReturn) { // we only query on the write DB if it's a write query, OR we've performed a write // by some other means if ($method == 'query') { if (isset($args[0])) { $sql = $args[0]; $code = isset($args[1]) ? $args[1] : E_USER_ERROR; if (in_array(strtolower(substr($sql, 0, strpos($sql, ' '))), $this->writeQueries) || $this->writePerformed) { $alternateReturn = $this->writeDb->query($sql, $code); $this->writePerformed = true; return false; } } } else { $i = call_user_func_array(array($this->writeDb, $method), $args); // capture a call to manipulate, which basically performs a bunch of write queries // at once if ($method == 'manipulate') { $this->writePerformed = true; } $alternateReturn = $i; return false; } }
function requireDefaultRecords() { parent::requireDefaultRecords(); if (!DataObject::get_one('DPSHostedPaymentPage')) { $page = new DPSHostedPaymentPage(); $page->Title = "Payment Status"; $page->URLSegment = "paymentstatus"; $page->ShowInMenus = 0; $page->ShowInSearch = 0; $page->write(); SS_Database::alterationMessage("DPSHostedPaymentPage page created", "created"); } }
/** * Generate the given field on the table, modifying whatever already exists as necessary. * * @param string $table The table name. * @param string $field The field name. * @param array|string $spec The field specification. If passed in array syntax, the specific database * driver takes care of the ALTER TABLE syntax. If passed as a string, its assumed to * be prepared as a direct SQL framgment ready for insertion into ALTER TABLE. In this case you'll * need to take care of database abstraction in your DBField subclass. */ public function requireField($table, $field, $spec) { //TODO: this is starting to get extremely fragmented. //There are two different versions of $spec floating around, and their content changes depending //on how they are structured. This needs to be tidied up. $fieldValue = null; $newTable = false; // backwards compatibility patch for pre 2.4 requireField() calls $spec_orig = $spec; if (!is_string($spec)) { $spec['parts']['name'] = $field; $spec_orig['parts']['name'] = $field; //Convert the $spec array into a database-specific string $spec = $this->{$spec}['type']($spec['parts'], true); } // Collations didn't come in until MySQL 4.1. Anything earlier will throw a syntax error if you try and use // collations. // TODO: move this to the MySQLDatabase file, or drop it altogether? if (!$this->database->supportsCollations()) { $spec = preg_replace('/ *character set [^ ]+( collate [^ ]+)?( |$)/', '\\2', $spec); } if (!isset($this->tableList[strtolower($table)])) { $newTable = true; } if (is_array($spec)) { $specValue = $this->{$spec_orig}['type']($spec_orig['parts']); } else { $specValue = $spec; } // We need to get db-specific versions of the ID column: if ($spec_orig == $this->IdColumn() || $spec_orig == $this->IdColumn(true)) { $specValue = $this->IdColumn(true); } if (!$newTable) { $fieldList = $this->fieldList($table); if (isset($fieldList[$field])) { if (is_array($fieldList[$field])) { $fieldValue = $fieldList[$field]['data_type']; } else { $fieldValue = $fieldList[$field]; } } } // Get the version of the field as we would create it. This is used for comparison purposes to see if the // existing field is different to what we now want if (is_array($spec_orig)) { $spec_orig = $this->{$spec_orig}['type']($spec_orig['parts']); } if ($newTable || $fieldValue == '') { $this->transCreateField($table, $field, $spec_orig); $this->alterationMessage("Field {$table}.{$field}: created as {$spec_orig}", "created"); } else { if ($fieldValue != $specValue) { // If enums/sets are being modified, then we need to fix existing data in the table. // Update any records where the enum is set to a legacy value to be set to the default. // One hard-coded exception is SiteTree - the default for this is Page. foreach (array('enum', 'set') as $enumtype) { if (preg_match("/^{$enumtype}/i", $specValue)) { $newStr = preg_replace("/(^{$enumtype}\\s*\\(')|('\$\\).*)/i", "", $spec_orig); $new = preg_split("/'\\s*,\\s*'/", $newStr); $oldStr = preg_replace("/(^{$enumtype}\\s*\\(')|('\$\\).*)/i", "", $fieldValue); $old = preg_split("/'\\s*,\\s*'/", $newStr); $holder = array(); foreach ($old as $check) { if (!in_array($check, $new)) { $holder[] = $check; } } if (count($holder)) { $default = explode('default ', $spec_orig); $default = $default[1]; if ($default == "'SiteTree'") { $default = "'Page'"; } $query = "UPDATE \"{$table}\" SET {$field}={$default} WHERE {$field} IN ("; for ($i = 0; $i + 1 < count($holder); $i++) { $query .= "'{$holder[$i]}', "; } $query .= "'{$holder[$i]}')"; $this->query($query); $amount = $this->database->affectedRows(); $this->alterationMessage("Changed {$amount} rows to default value of field {$field}" . " (Value: {$default})"); } } } $this->transAlterField($table, $field, $spec_orig); $this->alterationMessage("Field {$table}.{$field}: changed to {$specValue} <i style=\"color: #AAA\">(from {$fieldValue})</i>", "changed"); } } }
/** * Throw a database error */ function databaseError($message, $errorLevel = E_USER_ERROR) { if (!$this->mssql) { $errorMessages = array(); $errors = sqlsrv_errors(); if ($errors) { foreach ($errors as $error) { $errorMessages[] = $error['message']; } } $message .= ": \n" . implode("; ", $errorMessages); } return parent::databaseError($message, $errorLevel); }
/** * Ensure that the given table on the given connection has the given field * * @param SS_Database $conn connection * @param string $table Name of table * @param string $field Name of field * @param string $spec Spec to use if creating this field */ public function ensureTableHasColumn($conn, $table, $field, $spec) { $fields = $conn->fieldList($table); // Make column if not found if (!isset($fields[$field])) { $this->message(' * Creating ' . $field . ' on table ' . $table); $conn->createField($table, $field, $spec); } }
public function selectDatabase($name, $create = false, $errorLevel = E_USER_ERROR) { $this->fullTextEnabled = null; return parent::selectDatabase($name, $create, $errorLevel); }
/** * Injector injection point for schema manager * * @param DBQueryBuilder $queryBuilder */ public function setQueryBuilder(DBQueryBuilder $queryBuilder) { parent::setQueryBuilder($queryBuilder); return $this->realConn->setQueryBuilder($queryBuilder); }
function endSchemaUpdate() { parent::endSchemaUpdate(); $this->pragma('locking_mode', self::$default_pragma['locking_mode']); }
public function getSelectedDatabase() { if (self::model_schema_as_database()) { return $this->schemaToDatabaseName($this->schema); } return parent::getSelectedDatabase(); }