/** @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']); } }