예제 #1
0
 /**
  * Persist an object to the data store.  An insert or update will be executed based
  * on whether the primary key has a value.  use $form_insert to override this
  * in the case of a primary key that is not an auto_increment
  *
  * @access public
  * @param Object $obj the object to persist
  * @param bool $force_insert (default = false)
  * @return int the auto_increment id (insert) or the number of records updated (update)
  */
 public function Save($obj, $force_insert = false)
 {
     $objectclass = get_class($obj);
     $fms = $this->GetFieldMaps($objectclass);
     $pk = $obj->GetPrimaryKeyName();
     $id = $obj->{$pk};
     $table = $fms[$pk]->TableName;
     $pkcol = $fms[$pk]->ColumnName;
     $returnval = "";
     $pk_is_auto_insert = strlen($id) == 0;
     // if there is no value for the primary key, this is an insert
     $is_insert = $force_insert || $pk_is_auto_insert;
     // fire the OnSave event in case the object needs to prepare itself
     // if OnSave returns false, then don't proceed with the save
     $this->Observe("Firing " . get_class($obj) . "->OnSave({$is_insert})", OBSERVE_DEBUG);
     if (!$obj->OnSave($is_insert)) {
         $this->Observe("" . get_class($obj) . "->OnSave({$is_insert}) returned FALSE.  Exiting without saving", OBSERVE_WARN);
         return false;
     }
     $sql = "";
     if (!$is_insert) {
         // this is an update
         // remove this class from the cache before saving
         $this->DeleteCache($objectclass, $id);
         $sql = "update `{$table}` set ";
         $delim = "";
         foreach ($fms as $fm) {
             if (!$fm->IsPrimaryKey && $fm->FieldType != FM_CALCULATION) {
                 $prop = $fm->PropertyName;
                 $val = $obj->{$prop};
                 try {
                     $sql .= $delim . "`" . $fm->ColumnName . "` = " . $this->GetQuotedSql($val);
                 } catch (Exception $ex) {
                     throw new Exception("Error escaping property '{$prop}'. value could not be converted to string");
                 }
                 $delim = ", ";
             }
         }
         $sql .= " where {$pkcol} = '" . $this->Escape($id) . "'";
         $returnval = $this->DataAdapter->Execute($sql);
         $obj->OnUpdate();
         // fire OnUpdate event
     } else {
         // this is an insert
         $sql = "insert into `{$table}` (";
         $delim = "";
         foreach ($fms as $fm) {
             // we don't want to include the primary key if this is an auto-increment table
             if (!$fm->IsPrimaryKey || $force_insert) {
                 // calculated fields are not directly bound to a column and do not get persisted
                 if ($fm->FieldType != FM_CALCULATION) {
                     $prop = $fm->PropertyName;
                     $val = $obj->{$prop};
                     $sql .= $delim . "`" . $fm->ColumnName . "`";
                     $delim = ", ";
                 }
             }
         }
         $sql .= ") values (";
         $delim = "";
         foreach ($fms as $fm) {
             // use the save logic inserting values as with the column names above
             if (!$fm->IsPrimaryKey || $force_insert) {
                 if ($fm->FieldType != FM_CALCULATION) {
                     $prop = $fm->PropertyName;
                     $val = $obj->{$prop};
                     try {
                         $sql .= $delim . ' ' . $this->GetQuotedSql($val);
                     } catch (Exception $ex) {
                         throw new Exception("Error escaping property '{$prop}'. value could not be converted to string");
                     }
                     $delim = ", ";
                 }
             }
         }
         $sql .= ")";
         // for the insert we also need to get the insert id of the primary key
         $returnval = $this->DataAdapter->Execute($sql);
         if ($pk_is_auto_insert) {
             $returnval = $this->DataAdapter->GetLastInsertId();
             $obj->{$pk} = $returnval;
         }
         $obj->OnInsert();
         // fire OnInsert event
     }
     return $returnval;
 }