コード例 #1
0
ファイル: SparkRecord.php プロジェクト: sparkfun/sparklib
 /**
  * Insert a new record in the db.
  *
  * Calls preInsert() and postInsert(), if they are defined in the child
  * class.
  */
 public function insert()
 {
     $this->preInsert();
     $dbh = DB::getInstance();
     // build the list of things we actually care about inserting - those differing
     // from defaults, specifically:
     $insert_values = [];
     foreach ($this->_record as $insert_key => $insert_val) {
         if ($insert_val !== static::$_defaults[$insert_key]) {
             $insert_values[$insert_key] = $insert_val;
         }
     }
     if (!isset($insert_values[static::$_tableKey])) {
         $insert_values[static::$_tableKey] = DB::DefaultValue();
     }
     $numcols = count($insert_values);
     $q = 'INSERT INTO "' . static::$_tableName . '"';
     $cols = ' (';
     $vals = ' VALUES (';
     $insert_data = [];
     $i = 0;
     foreach ($insert_values as $col => $val) {
         $i++;
         $end = $i < $numcols ? ", " : ") ";
         // quote column names in case we run into a reserved word
         $cols .= '"' . $col . '"' . $end;
         $val = $this->typeJuggle($col, $val);
         if ($val instanceof DB\Literal) {
             $vals .= $val->literal();
         } else {
             $vals .= ':' . $col;
             // tack on to array for later execution of prep'd statement:
             $insert_data[$col] = $val;
         }
         $vals .= $end;
     }
     $q .= $cols . $vals;
     if ('pgsql' === constant('\\DB_SERVER_TYPE')) {
         $q .= ' RETURNING *';
     }
     try {
         $sth = $dbh->prepare($q);
         foreach ($insert_data as $col => $val) {
             $sth->bindValue(":{$col}", $val);
         }
         $sth->execute();
         if ('pgsql' === constant('\\DB_SERVER_TYPE')) {
             $insert_result = $sth->fetch(\PDO::FETCH_ASSOC);
             $this->loadFromRow($insert_result);
         } else {
             $this->_tableId = $dbh->lastInsertId();
         }
     } catch (Exception $e) {
         $failure_data_string = '';
         foreach ($insert_values as $failed_insert_column => $failed_insert_value) {
             if ($failed_insert_value instanceof DB\Literal) {
                 $failed_insert_value = $failed_insert_value->literal();
             }
             $failure_data_string .= "{$failed_insert_column}: {$failed_insert_value}; ";
         }
         throw new SparkRecordException('Insert failed: ' . $e->getMessage() . "\n[Query] " . $q . "\n[Values] {$failure_data_string}\n");
     }
     // We have an id now, so we could do a delete operation.
     $this->_canDelete = true;
     // try and keep this in synch
     $this->_record[static::$_tableKey] = $this->_tableId;
     if ($this->_logModifications || count($this->modificationInfo()) > 0) {
         $this->logModifications('INSERT', $this->_record);
     }
     $this->logInsert();
     $this->postInsert();
     // Reset the changes array and the _changed flag so that
     // any update() calls using the same dinosaur don't rewrite
     // those fields, and so that postUpdate() can behave sanely
     // in that case.
     $this->markUnchanged();
     return $this->_tableId;
 }