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();
 }