/** @override */
 public function saveItems(array $itemData, EarthIT_Schema_ResourceClass $rc, array $options = array())
 {
     EarthIT_Storage_Util::defaultSaveItemsOptions($options);
     $queries = $this->sqlGenerator->makeBulkSaveQueries($itemData, $rc, $options);
     $resultRows = array();
     foreach ($queries as $q) {
         list($sql, $params) = EarthIT_DBC_SQLExpressionUtil::templateAndParamValues($q);
         if ($q->returnsStuff()) {
             $resultRows = array_merge($resultRows, $this->sqlRunner->fetchRows($sql, $params));
         } else {
             $this->sqlRunner->doQuery($sql, $params);
         }
     }
     if ($options[EarthIT_Storage_ItemSaver::RETURN_SAVED]) {
         return $this->sqlGenerator->dbExternalToSchemaItems($resultRows, $rc);
     }
 }
 /**
  * TODO: Document how different stuffs get parsed.
  */
 public static function parseMulti($filters, EarthIT_Schema_ResourceClass $rc, EarthIT_Schema $schema = null, $fuzzyMatch = false)
 {
     if ($filters === '') {
         return self::emptyFilter();
     }
     if ($filters instanceof EarthIT_Storage_ItemFilter) {
         return $filters;
     }
     if (is_string($filters)) {
         $filters = array_map('urldecode', explode('&', $filters));
     }
     if (!is_array($filters)) {
         throw new Exception("'\$filters' parameter must be a string, an array, or an ItemFilter.");
     }
     foreach ($filters as $k => &$f) {
         if (is_string($k)) {
             //$f = "{$k}={$f}"; // ['ID' => 'foo'] = ['ID=foo']
             $f = self::parsePattern($k, $f, $rc, $schema, $fuzzyMatch);
         } else {
             $f = self::parse($f, $rc, $schema, $fuzzyMatch);
         }
     }
     unset($f);
     if (count($filters) == 1) {
         return EarthIT_Storage_Util::first($filters);
     }
     return new EarthIT_Storage_Filter_AndedItemFilter($filters);
 }
 public function updateItems(array $updatedFieldValues, EarthIT_Schema_ResourceClass $rc, EarthIT_Storage_ItemFilter $filter, array $options = array())
 {
     $rcName = $rc->getName();
     $matchedKeys = array();
     if (isset($this->items[$rcName])) {
         foreach ($this->items[$rcName] as $k => $item) {
             if ($filter->matches($item)) {
                 $matchedKeys[] = $k;
             }
         }
     }
     $updated = array();
     foreach ($matchedKeys as $k) {
         $item = $this->items[$rcName][$k];
         $item = $updatedFieldValues + $item;
         $id = EarthIT_Storage_Util::itemId($item, $rc);
         if ($id !== null and $id !== $k) {
             // TODO: Look at options to determine if updating is allowed
             // to overwrite other items
             unset($this->items[$rcName][$k]);
             $this->items[$rcName][$id] = $item;
             $k = $id;
         }
         $updated[$k] = $item;
     }
     return $updated;
 }
 public function makeUpdateQueries(array $updates, EarthIT_Storage_ItemFilter $filter, EarthIT_Schema_ResourceClass $rc, array $options = array())
 {
     if (count($updates) == 0) {
         throw new Exception("Not updating anything!");
         // Maybe we could allow that?  In which case this just becomes a search.
         // Would have to construct the query differently in that case.
     }
     // TODO: Mind the options.
     // This code was copied from _bulkPatchyQueries
     // and committed as soon as the unit test passed.
     // It's probably a bit of a mess.
     // Refactor it if you want to.
     $params = array();
     $PB = new EarthIT_DBC_ParamsBuilder($params);
     $params['table'] = $this->rcTableExpression($rc);
     $conditions = $filter->toSql('stuff', $this->dbObjectNamer, $PB);
     $storableFields = EarthIT_Storage_Util::storableFields($rc);
     $outputColumnValueSqls = array();
     $inputColumnValueSqls = array();
     $columnParamNames = array();
     $fieldsByColumnName = array();
     $columnUpdates = array();
     foreach ($storableFields as $fn => $f) {
         $columnName = $this->dbObjectNamer->getColumnName($rc, $f);
         $fieldColumnNames[$fn] = $columnName;
         $fieldsByColumnName[$columnName] = $f;
         $columnParamName = $PB->newParam('c_');
         $columnParamNames[$columnName] = $columnParamName;
         $params[$columnParamName] = new EarthIT_DBC_SQLIdentifier($columnName);
         $columnValueParamName = $PB->newParam("v_");
         $columnValueParamNames[$columnName] = $columnValueParamName;
         if (array_key_exists($fn, $updates)) {
             $params[$columnValueParamName] = $updates[$fn];
             $columnUpdates[$columnName] = null;
             // Value never actually gets used kekeke
         }
         $columnValueSelectSql = $this->dbInternalToExternalValueSql($f, $rc, "{{$columnParamName}}");
         if ($columnValueSelectSql !== "{{$columnParamName}}") {
             $columnValueSelectSql .= "AS {{$columnParamName}}";
         }
         $outputColumnValueSqls[$columnName] = $columnValueSelectSql;
         $inputColumnValueSqls[$columnName] = $this->dbExternalToInternalValueSql($f, $rc, "{{$columnValueParamName}}");
     }
     $sets = $this->encodeColumnValuePairs($columnUpdates, $columnParamNames, $columnValueParamNames, $rc, $fieldsByColumnName);
     $sql = "UPDATE {table} AS stuff\n" . "SET\n\t" . implode(",\n\t", $sets) . "\n" . "WHERE {$conditions}\n" . "RETURNING\n\t" . implode(",\n\t", $outputColumnValueSqls);
     $returnSaved = true;
     // TODO: Only if requested by options
     return array(new EarthIT_Storage_StorageQuery($sql, $params, $returnSaved));
 }
 public function testGeoJsonStorageAndRetrieval()
 {
     $orgRc = $this->registry->schema->getResourceClass('organization');
     $newOrgs = self::keyById($this->storage->saveItems(array(array('name' => 'Test Org', 'office location' => array('type' => 'Point', 'coordinates' => array(43.06733098, -89.39270496), 'crs' => array('type' => 'name', 'properties' => array('name' => 'EPSG:4326'))))), $orgRc, array(EarthIT_Storage_ItemSaver::RETURN_SAVED => true)));
     foreach ($newOrgs as $newOrg) {
         $loc = $newOrg['office location'];
         $this->assertTrue(is_array($loc));
         $this->assertEquals('Point', $loc['type']);
         $this->assertEquals(43, round($loc['coordinates'][0]));
         $this->assertEquals(-89, round($loc['coordinates'][1]));
         $this->assertEquals('EPSG:4326', $loc['crs']['properties']['name']);
     }
     $fetchedOrgs = self::keyById(EarthIT_Storage_Util::getItemsById(array_keys($newOrgs), $orgRc, $this->storage));
     foreach ($fetchedOrgs as $newOrg) {
         $loc = $newOrg['office location'];
         $this->assertTrue(is_array($loc));
         $this->assertEquals('Point', $loc['type']);
         $this->assertEquals(43, round($loc['coordinates'][0]));
         $this->assertEquals(-89, round($loc['coordinates'][1]));
         $this->assertEquals('EPSG:4326', $loc['crs']['properties']['name']);
     }
     // Now let's upsert!
     $orgUpdatess = array();
     foreach ($fetchedOrgs as $fetchedOrg) {
         $fetchedOrg['office location']['coordinates'][0] += 1;
         $orgUpdatess[] = $fetchedOrg;
     }
     $updatedOrgs = self::keyById($this->storage->saveItems($orgUpdatess, $orgRc, array(EarthIT_Storage_ItemSaver::RETURN_SAVED => true, EarthIT_Storage_ItemSaver::ON_DUPLICATE_KEY => EarthIT_Storage_ItemSaver::ODK_UPDATE)));
     foreach ($updatedOrgs as $updatedOrg) {
         $loc = $updatedOrg['office location'];
         $this->assertTrue(is_array($loc));
         $this->assertEquals('Point', $loc['type']);
         $this->assertEquals(44, round($loc['coordinates'][0]));
         $this->assertEquals(-89, round($loc['coordinates'][1]));
         $this->assertEquals('EPSG:4326', $loc['crs']['properties']['name']);
     }
 }