Пример #1
0
 function test_set_indexed_record()
 {
     $s = new Dataface_Record('Profiles', array());
     $s->clearValues();
     $s->setValue('id', 10);
     $this->assertEquals($s->getValue('addresses.city', 1), 'Springfield');
     //$s->setValue('addresses.city', 'Houston', 1);
     //$this->assertEquals( $s->getValue('addresses.city', 1), 'Houston');
     //$s->setValue('addresses.city', 'LA', array('id'=>2) );
     //$this->assertEquals( $s->getValue('addresses.city', 1), 'LA');
     //$this->assertEquals( $s->getValue('addresses.city', array('id'=>2)), 'LA');
 }
Пример #2
0
 /**
  * Returns true if the record currently represented in the Table already exists 
  * in the database.
  *
  * @param tablename Alternative table where records may be stored.  This is useful if we are reading form import or delete tables.
  *
  */
 function recordExists(&$record, $keys = null, $tablename = null)
 {
     if (!is_a($record, "Dataface_Record")) {
         trigger_error(df_translate('scripts.Dataface.IO.recordExists.ERROR_PARAMETER_1', "In Dataface_IO::recordExists() the first argument is expected to be either a 'Dataface_Record' object or an array of key values, but received neither.\n<br>") . Dataface_Error::printStackTrace(), E_USER_ERROR);
     }
     if ($tablename === null and $this->_altTablename !== null) {
         $tablename = $this->_altTablename;
     }
     $tempRecordCreated = false;
     if ($record->snapshotExists()) {
         $tempRecord = new Dataface_Record($record->_table->tablename, $record->getSnapshot());
         $tempRecordCreated = true;
     } else {
         $tempRecord =& $record;
     }
     if ($keys == null) {
         // Had to put in userialize(serialize(...)) because getValues() returns by reference
         // and we don't want to change actual values.
         $query = unserialize(serialize($tempRecord->getValues(array_keys($record->_table->keys()))));
     } else {
         $query = $keys;
     }
     $table_keys = array_keys($this->_table->keys());
     foreach ($table_keys as $key) {
         if (!isset($query[$key]) or !$query[$key]) {
             //trigger_error("In Dataface_IO::recordExists()d attempt to determine if a record exists, not enough information was given.  At least ALL of the keys of the table in question ('".$this->_table->tablename."') must be included in the provided Dataface_Record object (or query array), but some keys (notably '$key') are missing.  Impossible to determine existence unless all key fields are provided.\n<br>".Dataface_Error::printStackTrace(), E_USER_ERROR);
             return false;
         }
     }
     foreach (array_keys($query) as $key) {
         $query[$key] = '=' . $this->_serializer->serialize($key, $tempRecord->getValue($key));
     }
     $qb = new Dataface_QueryBuilder($this->_table->tablename, $query);
     $sql = $qb->select_num_rows(array(), $this->tablename($tablename));
     $res = mysql_query($sql, $this->_table->db);
     // We just use regular mysql query to see if record exists because this should be sufficient
     //$res = $this->dbObj->query($sql, $this->_table->db, $this->lang);
     if (!$res || PEAR::isError($res)) {
         die("SQL error in {$sql} : " . mysql_error($this->_table->db) . Dataface_Error::printStackTrace());
     }
     list($rows) = mysql_fetch_row($res);
     mysql_free_result($res);
     if ($rows > 1) {
         $err = PEAR::raiseError(Dataface_LanguageTool::translate('recordExists failure. Too many rows returned.', "Test for existence of record in recordExists() returned {$rows} records.  \n\t\t\t\t\tIt should have max 1 record.  \n\t\t\t\t\tThe query must be incorrect.  \n\t\t\t\t\tThe query used was '{$sql}'.  On line " . __LINE__ . " of file " . __FILE__, array('table' => $this->_table->tablename, 'line' => __LINE__, 'file' => __FILE__, 'sql' => $sql)), DATAFACE_E_IO_ERROR);
         trigger_error($err->toString() . "\n<br>" . Dataface_Error::printStackTrace());
     }
     if ($tempRecordCreated) {
         $tempRecord->__destruct();
     }
     return intval($rows) === 1;
 }
Пример #3
0
 /**
  * Returns true if the record currently represented in the Table already exists 
  * in the database.
  *
  * @param tablename Alternative table where records may be stored.  This is useful if we are reading form import or delete tables.
  *
  */
 function recordExists(&$record, $keys = null, $tablename = null)
 {
     $this->lastVersionNumber = null;
     if (!is_a($record, "Dataface_Record")) {
         throw new Exception(df_translate('scripts.Dataface.IO.recordExists.ERROR_PARAMETER_1', "In Dataface_IO::recordExists() the first argument is expected to be either a 'Dataface_Record' object or an array of key values, but received neither.\n<br>"), E_USER_ERROR);
     }
     if ($tablename === null and $this->_altTablename !== null) {
         $tablename = $this->_altTablename;
     }
     $tempRecordCreated = false;
     if ($record->snapshotExists()) {
         $tempRecord = new Dataface_Record($record->_table->tablename, $record->getSnapshot());
         $tempRecordCreated = true;
     } else {
         $tempRecord =& $record;
     }
     if ($keys == null) {
         // Had to put in userialize(serialize(...)) because getValues() returns by reference
         // and we don't want to change actual values.
         $query = unserialize(serialize($tempRecord->getValues(array_keys($record->_table->keys()))));
     } else {
         $query = $keys;
     }
     $table_keys = array_keys($this->_table->keys());
     foreach ($table_keys as $key) {
         if (!isset($query[$key]) or !$query[$key]) {
             return false;
         }
     }
     foreach (array_keys($query) as $key) {
         //$query[$key] = '='.$this->_serializer->serialize($key, $tempRecord->getValue($key) );
         $query[$key] = $this->_serializer->serialize($key, $tempRecord->getValue($key));
     }
     if ($tempRecordCreated) {
         $tempRecord->__destruct();
     }
     //$qb = new Dataface_QueryBuilder($this->_table->tablename, $query);
     //$sql = $qb->select_num_rows(array(), $this->tablename($tablename));
     if ($record->table()->isVersioned()) {
         $versionField = "`" . $record->table()->getVersionField() . "`";
     } else {
         $versionField = "NULL";
     }
     $sql = "select `" . $table_keys[0] . "`, {$versionField} from `" . $this->tablename($tablename) . "` where ";
     $where = array();
     foreach ($query as $key => $val) {
         $where[] = '`' . $key . "`='" . addslashes($val) . "'";
     }
     $sql .= implode(' AND ', $where) . ' limit 1';
     $res = df_q($sql, $this->_table->db);
     $num = xf_db_num_rows($res);
     $row = xf_db_fetch_row($res);
     @xf_db_free_result($res);
     if ($num === 1) {
         // We have the correct number...
         // let's check the version
         $this->lastVersionNumber = intval($row[1]);
         return true;
     }
     if ($num > 1) {
         $err = PEAR::raiseError(Dataface_LanguageTool::translate('recordExists failure. Too many rows returned.', "Test for existence of record in recordExists() returned {$rows} records.  \n\t\t\t\t\tIt should have max 1 record.  \n\t\t\t\t\tThe query must be incorrect.  \n\t\t\t\t\tThe query used was '{$sql}'. ", array('table' => $this->_table->tablename, 'line' => 0, 'file' => '_', 'sql' => $sql)), DATAFACE_E_IO_ERROR);
         throw new Exception($err->toString(), E_USER_ERROR);
     }
     return false;
 }
Пример #4
0
 /**
  * Gets the value for a field.
  *
  * @param $fieldname The name of the field whose value we are retrieving.  This may be either a relative
  *					 fieldname or an absolute column name.
  * @type string
  */
 function getValue($fieldname)
 {
     $this->_initValues();
     if (strpos($fieldname, '.') === false) {
         if (!array_key_exists($fieldname, $this->_values)) {
             // The key does not exist as a normal field -- so check if it is a calculated field.
             $tables = $this->_relationship->getDestinationTables();
             $dt =& Dataface_Table::loadTable($this->_relationship->getDomainTable());
             if ($dt->hasField($fieldname)) {
                 echo "Domain table has {$fieldname}";
                 $tables = array($this->_relationship->getDomainTable());
             } else {
                 echo "Domain table doesn't have {$fieldname}";
             }
             foreach (array_keys($tables) as $tkey) {
                 if ($tables[$tkey]->hasField($fieldname)) {
                     $tempRecord = new Dataface_Record($tables[$tkey]->tablename, $this->getValues());
                     return $tempRecord->getValue($fieldname);
                 }
             }
             trigger_error("Attempt to get value for fieldname '{$fieldname}' that does not exist in related record of relationship '" . $this->_relationshipName . "'.  Acceptable values include {" . implode(', ', array_keys($this->_values)) . "}.\n<br>" . Dataface_Error::printStackTrace(), E_USER_ERROR);
         }
         return $this->_values[$fieldname];
     } else {
         list($table, $field) = explode('.', $fieldname);
         return $this->getValue($field);
     }
 }
Пример #5
0
 function test_relationships()
 {
     $record = new Dataface_Record('Profiles', array());
     $record->setValue('id', 10);
     $record->setValue('fname', 'John');
     $table =& $this->table1;
     $this->table1->relationships();
     // loads the relationships
     // make sure that the relationships were loaded properly
     $rels = array('appointments', 'degrees', 'addresses');
     foreach ($rels as $rel) {
         $this->assertTrue(is_a($table->_relationships[$rel], 'Dataface_Relationship'), "Relationship {$rel} not loaded");
     }
     //make sure the sql was loaded properly
     $appointments =& $table->getRelationship('appointments');
     $this->assertEquals($appointments->_schema['sql'], "select * from Appointments where Appointments.profileid='\$id'");
     $this->assertEquals($record->parseString($appointments->_schema['sql']), "select * from Appointments where Appointments.profileid='10'");
     $this->assertEquals(count($appointments->_schema['tables']), 1);
     $this->assertEquals($appointments->_schema['tables'][0], 'Appointments');
     $this->assertEquals(count($appointments->_schema['selected_tables']), 1);
     $this->assertEquals($appointments->_schema['selected_tables'][0], 'Appointments');
     $this->assertEquals(count($appointments->_schema['columns']), 6);
     //(profileid, position, startdate, enddate, salary)
     $this->assertEquals($appointments->_schema['columns'][0], 'Appointments.id');
     $this->assertEquals($appointments->_schema['columns'][1], 'Appointments.profileid');
     $this->assertEquals($appointments->_schema['columns'][2], 'Appointments.position');
     $this->assertEquals($appointments->_schema['columns'][3], 'Appointments.startdate');
     $this->assertEquals($appointments->_schema['columns'][4], 'Appointments.enddate');
     $this->assertEquals($appointments->_schema['columns'][5], 'Appointments.salary');
     $degrees =& $table->getRelationship('degrees');
     $this->assertEquals($degrees->_schema['sql'], "select name, institution from Degrees where Degrees.profileid='\$id'");
     $this->assertEquals($record->parseString($degrees->_schema['sql']), "select name, institution from Degrees where Degrees.profileid='10'");
     $this->assertEquals(count($degrees->_schema['tables']), 1);
     $this->assertEquals($degrees->_schema['tables'][0], 'Degrees');
     $this->assertEquals(count($degrees->_schema['columns']), 2);
     $this->assertEquals($degrees->_schema['columns'][0], 'Degrees.name');
     $this->assertEquals($degrees->_schema['columns'][1], 'Degrees.institution');
     $courses =& $table->getRelationship('courses');
     $this->assertEquals($courses->_schema['selected_tables'][0], 'Courses');
     $this->assertEquals(count($courses->_schema['columns']), 4);
     $this->assertEquals($courses->_schema['sql'], "select Courses.* from Courses, Student_Courses where Courses.id=Student_Courses.courseid and Student_Courses.studentid='\$id'");
     // try default get related... should only return 3 records
     unset($degrees);
     $degrees = $record->getRelatedRecords('degrees');
     $this->assertEquals($degrees[0]['name'], 'Master of Technology');
     $this->assertEquals(count($degrees), 3, 'Degrees relationship returned wrong number of records.  Should be 3.');
     foreach ($degrees as $degree) {
         $this->assertTrue(isset($degree['name']), 'name is not set for ' . $degree);
         $this->assertTrue(isset($degree['institution']), 'institution is not set for' . $degree);
     }
     // Explicitly request multiple records
     $degrees = $record->getRelatedRecords('degrees', true);
     $this->assertEquals($degrees[0]['name'], 'Master of Technology');
     $this->assertEquals(count($degrees), 3, 'Degrees relationship returned wrong number of records.  Should be 3.');
     foreach ($degrees as $degree) {
         $this->assertTrue(isset($degree['name']), 'name is not set for ' . $degree);
         $this->assertTrue(isset($degree['institution']), 'institution is not set for' . $degree);
     }
     // Explicitly request single record
     $degrees = $record->getRelatedRecords('degrees', false);
     $this->assertEquals($degrees['name'], 'Master of Technology');
     $this->assertTrue(isset($degrees['name']), 'name is not set for ' . $degree);
     $this->assertTrue(isset($degrees['institution']), 'institution is not set for' . $degree);
     // Try using getValue()
     $this->assertEquals($record->getValue('degrees.name'), 'Master of Technology');
     // Try multiple values
     //$names = $record->getValue('degrees.name', true);
     //$this->assertEquals(3, count($names), 'Wrong number of names returned for getValue(degrees.name)');
     //$this->assertEquals($names[0], 'Master of Technology');
     //$this->assertEquals($names[1], 'PH.D of Technology');
     //$this->assertEquals($names[2], 'Bachelor of Science');
     //
     //  Now we use a relationship that was defined directly with SQL
     //(profileid,line1,line2,line3,city,state,country,postalcode)
     $addresses =& $this->table1->getRelationship('addresses');
     $this->assertEquals($addresses->_schema['sql'], "select * from Addresses where profileid='\$id'");
     $this->assertEquals($record->parseString($addresses->_schema['sql']), "select * from Addresses where profileid='10'");
     $this->assertEquals(count($addresses->_schema['tables']), 1);
     $this->assertEquals(count($addresses->_schema['columns']), 9);
     $this->assertEquals($addresses->_schema['tables'][0], 'Addresses');
     $this->assertEquals($addresses->_schema['columns'][0], 'Addresses.id');
     $this->assertEquals($addresses->_schema['columns'][1], 'Addresses.profileid');
     $this->assertEquals($addresses->_schema['columns'][2], 'Addresses.line1');
     $this->assertEquals($addresses->_schema['columns'][3], 'Addresses.line2');
     $line1 = $record->getValue('addresses.line1');
     $this->assertEquals($line1, '555 Elm St');
 }
Пример #6
0
 public function buildRecord(xatacard_layout_Schema $schema, Dataface_Record $rec)
 {
     //Now we populate the record
     $out = new xatacard_layout_Record();
     $out->setSchema($schema);
     $out->setDataSource($this);
     $recordCache = array();
     $recordCache[$rec->getId()] = $rec;
     $recordData = array('records' => array(), 'fields' => array());
     $recordIdToIndex = array();
     foreach ($schema->getFields() as $key => $value) {
         if (strpos($key, '/') !== false) {
             // this is a first class property of the record so we can just get it.
             $index = count($recordData['records']);
             $recordData['records'][$index] = array('id' => $rec->getId(), 'version' => $rec->getVersion());
             $recordIdToIndex[$rec->getId()] = $index;
             $recordData['fields'][$key] = $recordIdToIndex[$rec->getId()];
             $out->setValue($key, $rec->getValue($key));
         } else {
             // this is a related record's property that we need to get from the related
             // records.
             $path = explode('/', $key);
             $crec = $rec;
             // As we're going to be going through related records
             // we need to mark the current record we are dealing
             /// with
             $fieldName = array_pop($path);
             // A flag to indicate if we should break the outer loop
             // after the inner loop finishes
             $shouldSkip = false;
             foreach ($path as $part) {
                 $index = 0;
                 if (preg_match('/^(.*)\\[(\\d+\\)]$/', $part, $matches)) {
                     $index = intval($matches[2]);
                     $part = $matches[1];
                 }
                 $related = $crec->getRelatedRecord($part, $index);
                 if (PEAR::isError($related)) {
                     throw new Exception(sprintf("MySQL datasource failed to load record because there was an error retrieving a column from a related record.  The field '%s' could not be retrieved because the following error: %s", $key, $related->getMessage()));
                 }
                 if (!$related) {
                     // No related record could be found to satisfy this path.
                     // This doesn't constitute an error.  It just means that the
                     // value should be blank.
                     $out->setValue($key, null);
                     $shouldSkip = true;
                     break;
                 }
                 unset($crec);
                 if (@$this->recordCache[$related->getId()]) {
                     $crec = $this->recordCache[$related->getId()];
                 } else {
                     $crec = $related->toRecord();
                     $this->recordCache[$related->getId()] = $crec;
                     $index = count($recordData['records']);
                     $recordData['records'][$index] = array('id' => $crec->getId(), 'version' => $rec->getVersion());
                     $recordIdToIndex[$crec->getId()] = $index;
                 }
                 unset($related);
             }
             if ($shouldSkip) {
                 // Something occurred in the inner loop to
                 // complete this step so we should skip the rest
                 // of this stuff.
                 continue;
             }
             if (!$crec) {
                 // This should never happen
                 throw new Exception(sprintf("MySQL datasource failed to load record because there was an error retrieving a related record required for one of the fields.  The field '%s' could not be retrieved.", $key));
             }
             $recordData['fields'][$key] = $recordIdToIndex[$crec->getId()];
             $out->setValue($key, $crec->val($fieldName));
         }
     }
     $cacheKeys = array_keys($recordCache);
     sort($cacheKeys);
     $versionstring = array();
     foreach ($cacheKeys as $k) {
         $versionstring[] = $k . ':' . $recordCache[$k]->getVersion();
     }
     $versionstring = implode(' ', $versionstring);
     $versionhash = md5($versionstring);
     $res = $this->query(sprintf("select `id` from `%s` where \n\t\t\t\tschema_id=%d and \n\t\t\t\tbase_record_id_hash='%s' and \n\t\t\t\tversion_hash='%s' and\n\t\t\t\t`lang`='%s'", str_replace('`', '', self::$RECORDS_TABLE), intval($schema->getId()), addslashes(md5($rec->getId())), addslashes($versionhash), addslashes($rec->lang)));
     if (xf_db_num_rows($res) >= 0) {
         $row = xf_db_fetch_row($res);
         $out->setId($row[0]);
     } else {
         $res = $this->query(sprintf("insert into `%s` (schema_id, base_record_id_hash, base_record_id, version_hash, `lang`, `record_data`)\n\t\t\t\tvalues (\n\t\t\t\t\t%d, '%s', '%s', '%s', '%s'\n\t\t\t\t)", intval($schema->getId()), addslashes(md5($rec->getId())), addslashes($rec->getid()), addslashes($versionhash), addslashes($rec->lang), addslashes(json_encode($recordData))));
         $out->setId(xf_db_insert_id(df_db()));
     }
     $out->clearSnapshot();
     return $out;
 }