Beispiel #1
0
 public static function getRevisionRecords($options = array())
 {
     $options = static::prepareOptions($options, array('indexField' => false, 'conditions' => array(), 'order' => false, 'limit' => false, 'offset' => 0));
     $query = 'SELECT * FROM `%s` WHERE (%s)';
     $params = array(static::getHistoryTable(), count($options['conditions']) ? join(') AND (', static::_mapConditions($options['conditions'])) : 1);
     if ($options['order']) {
         $query .= ' ORDER BY ' . join(',', static::_mapFieldOrder($options['order']));
     }
     if ($options['limit']) {
         $query .= sprintf(' LIMIT %u,%u', $options['offset'], $options['limit']);
     }
     if ($options['indexField']) {
         return DB::table(static::_cn($options['indexField']), $query, $params);
     } else {
         return DB::allRecords($query, $params);
     }
 }
Beispiel #2
0
 public function save($deep = true, $createRevision = true)
 {
     $wasDirty = false;
     if ($this->isDirty && $createRevision) {
         // update creation time / user
         $this->Created = time();
         $this->CreatorID = $_SESSION['User'] ? $_SESSION['User']->ID : null;
         $wasDirty = true;
     }
     // save record as usual
     $return = parent::save($deep);
     if ($wasDirty && $createRevision) {
         // save a copy to history table
         $recordValues = $this->_prepareRecordValues();
         $set = static::_mapValuesToSet($recordValues);
         DB::nonQuery('INSERT INTO `%s` SET %s', array(static::$historyTable, join(',', $set)));
     }
 }
Beispiel #3
0
 public static function getCreateTable($recordClass, $historyVariant = false)
 {
     $queryFields = array();
     $indexes = $historyVariant ? array() : $recordClass::$indexes;
     $fulltextColumns = array();
     // history table revisionID field
     if ($historyVariant) {
         $queryFields[] = '`RevisionID` int(10) unsigned NOT NULL auto_increment';
         $queryFields[] = 'PRIMARY KEY (`RevisionID`)';
     }
     // compile fields
     $rootClass = !empty($recordClass::$rootClass) ? $recordClass::$rootClass : $recordClass;
     foreach ($recordClass::getClassFields() as $fieldId => $field) {
         //Debug::dump($field, "Field: $field[columnName]");
         if ($field['columnName'] == 'RevisionID') {
             continue;
         }
         // force notnull=false on non-rootclass fields
         if ($rootClass && !$rootClass::_fieldExists($fieldId)) {
             $field['notnull'] = false;
         }
         // auto-prepend class type
         if ($field['columnName'] == 'Class' && $field['type'] == 'enum' && !in_array($rootClass, $field['values']) && empty($rootClass::$subClasses)) {
             array_unshift($field['values'], $rootClass);
         }
         // escape namespaces in field names
         if ($field['columnName'] == 'Class') {
             foreach ($field['values'] as $index => $value) {
                 $field['values'][$index] = str_replace('\\', '\\\\', $value);
             }
         }
         $fieldDef = '`' . $field['columnName'] . '`';
         $fieldDef .= ' ' . static::getSQLType($field);
         $fieldDef .= ' ' . ($field['notnull'] ? 'NOT NULL' : 'NULL');
         if ($field['autoincrement'] && !$historyVariant) {
             $fieldDef .= ' auto_increment';
         } elseif ($field['type'] == 'timestamp' && $field['default'] == 'CURRENT_TIMESTAMP') {
             $fieldDef .= ' default CURRENT_TIMESTAMP';
         } elseif (empty($field['notnull']) && $field['default'] == null) {
             $fieldDef .= ' default NULL';
         } elseif (isset($field['default'])) {
             if ($field['type'] == 'boolean') {
                 $fieldDef .= ' default ' . ($field['default'] ? 1 : 0);
             } else {
                 $fieldDef .= ' default "' . DB::escape($field['default']) . '"';
             }
         }
         $queryFields[] = $fieldDef;
         if ($field['primary']) {
             if ($historyVariant) {
                 $queryFields[] = 'KEY `' . $field['columnName'] . '` (`' . $field['columnName'] . '`)';
             } else {
                 $queryFields[] = 'PRIMARY KEY (`' . $field['columnName'] . '`)';
             }
         }
         if ($field['unique'] && !$historyVariant) {
             $queryFields[] = 'UNIQUE KEY `' . $field['columnName'] . '` (`' . $field['columnName'] . '`)';
         }
         if ($field['index'] && !$historyVariant) {
             $queryFields[] = 'KEY `' . $field['columnName'] . '` (`' . $field['columnName'] . '`)';
         }
         if ($field['fulltext'] && !$historyVariant) {
             $fulltextColumns[] = $field['columnName'];
         }
     }
     // context index
     if (!$historyVariant && $recordClass::_fieldExists('ContextClass') && $recordClass::_fieldExists('ContextID')) {
         $queryFields[] = 'KEY `CONTEXT` (`' . $recordClass::getColumnName('ContextClass') . '`,`' . $recordClass::getColumnName('ContextID') . '`)';
     }
     // compile indexes
     foreach ($indexes as $indexName => $index) {
         if (is_array($index['fields'])) {
             $indexFields = $index['fields'];
         } elseif ($index['fields']) {
             $indexFields = array($index['fields']);
         } else {
             continue;
         }
         // translate field names
         foreach ($index['fields'] as &$indexField) {
             $indexField = $recordClass::getColumnName($indexField);
         }
         if (!empty($index['fulltext'])) {
             $fulltextColumns = array_unique(array_merge($fulltextColumns, $index['fields']));
             continue;
         }
         $queryFields[] = sprintf('%s KEY `%s` (`%s`)', !empty($index['unique']) ? 'UNIQUE' : '', $indexName, join('`,`', $index['fields']));
     }
     if (!empty($fulltextColumns)) {
         $queryFields[] = 'FULLTEXT KEY `FULLTEXT` (`' . join('`,`', $fulltextColumns) . '`)';
     }
     $createSQL = sprintf("--\n-- %s for class %s\n--\n" . "CREATE TABLE IF NOT EXISTS `%s` (\n\t%s\n) ENGINE=MyISAM DEFAULT CHARSET=%s;", $historyVariant ? 'History table' : 'Table', $recordClass, $historyVariant ? $recordClass::$historyTable : $recordClass::$tableName, join("\n\t,", $queryFields), DB::$charset);
     return $createSQL;
 }
Beispiel #4
0
 public static function handleError($query = null, $queryLog = null, $parameters = null)
 {
     $Connection = DB::getConnection();
     if ($Connection->errorCode() == '42S02' && static::$autoCreateTables) {
         $CreateTable = SQL::getCreateTable(static::$rootClass);
         // history versions table
         if (static::isVersioned()) {
             $CreateTable .= SQL::getCreateTable(static::$rootClass, true);
         }
         $Statement = $Connection->query($CreateTable);
         // check for errors
         $ErrorInfo = $Statement->errorInfo();
         // handle query error
         if ($ErrorInfo[0] != '00000') {
             self::handleError($query, $queryLog, $errorHandler);
         }
         // clear buffer (required for the next query to work without running fetchAll first
         $Statement->closeCursor();
         return $Connection->query($query);
         // now the query should finish with no error
     } else {
         return DB::handleError($query, $queryLog, $parameters);
     }
 }