Skip to content

Commit

Permalink
Merge branch 'master' into key-properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Walder committed Feb 11, 2016
2 parents 14338b9 + e1c36bf commit 2039923
Show file tree
Hide file tree
Showing 22 changed files with 371 additions and 15 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: php

php:
- 5.4
- 5.5
- 5.6
- 7.0
Expand Down
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This library is intended to make it easier for you to get started with and to us
- [Getting Started](#getting-started)
- [Defining Your Model](#defining-your-model)
- [Creating Records](#creating-records)
- [Geopoint Support](#geopoint)
- [Queries, GQL & The Default Query](#queries-gql--the-default-query)
- [Multi-tenant Applications & Data Namespaces](#multi-tenant-applications--data-namespaces)
- [Entity Groups, Hierarchy & Ancestors](#entity-groups-hierarchy--ancestors)
Expand Down Expand Up @@ -131,7 +132,7 @@ If you want to use the JSON API from remote or non-App Engine environments, you

To install using Composer, use this require line, for production

`"tomwalder/php-gds": "v2.0.1"`
`"tomwalder/php-gds": "v2.1.0"`

For older, version 1 series

Expand Down Expand Up @@ -168,6 +169,7 @@ Available Schema configuration methods:
- `GDS\Schema::addFloat`
- `GDS\Schema::addBoolean`
- `GDS\Schema::addStringList`
- `GDS\Schema::addGeopoint` *(not supported over JSON API)*

Take a look at the `examples` folder for a fully operational set of code.

Expand All @@ -185,6 +187,12 @@ $obj_book = $obj_book_store->createEntity([
]);
```

## Special Properties ##

Other than scalar values, there are two "object" data types supported:

### DateTime ###

Support for DateTime object binding (also see query parameter binding below)

```php
Expand All @@ -196,6 +204,31 @@ $obj_book = $obj_book_store->createEntity([
]);
```

### Geopoint ###

The library has recently had support added for Geopoint properties.

```php
$obj_schema->addGeopoint('location');
```

Then when setting data, use the `Geopoint` object

```php
$obj_person->location = new GDS\Property\Geopoint(53.4723272, -2.2936314);
```

And when pulling geopoint data out of a result:

```php
echo $obj_persion->location->getLatitude();
echo $obj_persion->location->getLongitude();
```

**It is not currently possible to query Geopoint fields, although this feature is in Alpha with Google**

**Geopoint data is only supported using the native Protocol Buffer API. It will work well on App Engine and in development, but not via the JSON API**

## Queries, GQL & The Default Query ##

At the time of writing, the `GDS\Store` object uses Datastore GQL as its query language. Here is an example:
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
],
"require": {
"php": ">=5.4.0"
"php": ">=5.5.0"
},
"suggest": {
"google/apiclient": "Allows you to use the JSON API Gateway/Datastore endpoints. Tested with 1.1.6"
Expand Down
4 changes: 2 additions & 2 deletions examples/BookStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ class BookStore extends GDS\Store
*/
protected function buildSchema()
{
$this->setEntityClass('\\Book');
return (new GDS\Schema('Book'))
->addString('title')
->addString('author')
->addString('isbn', TRUE);
->addString('isbn', TRUE)
->setEntityClass('\\Book');
}

}
2 changes: 1 addition & 1 deletion examples/ancestor_key_lookups.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

$obj_person_schema = (new GDS\Schema('Person'))->addString('name')->addString('description');

$obj_store = new GDS\Store($obj_gateway, $obj_person_schema);
$obj_store = new GDS\Store($obj_person_schema, $obj_gateway);

// Load the parent (run 'ancestor_keys.php' if needed to create it)
$obj_stored_parent = $obj_store->fetchOne("SELECT * FROM Person WHERE __key__ = KEY(Person, 'parent@example.com')");
Expand Down
2 changes: 1 addition & 1 deletion examples/ancestor_keys.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

$obj_person_schema = (new GDS\Schema('Person'))->addString('name')->addString('description');

$obj_store = new GDS\Store($obj_gateway, $obj_person_schema);
$obj_store = new GDS\Store($obj_person_schema, $obj_gateway);

// Create the parent
$obj_john = new \GDS\Entity();
Expand Down
2 changes: 1 addition & 1 deletion examples/ancestor_keys_auto_insert.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

$obj_person_schema = (new GDS\Schema('Person'))->addString('name')->addString('description');

$obj_store = new GDS\Store($obj_gateway, $obj_person_schema);
$obj_store = new GDS\Store($obj_person_schema, $obj_gateway);

// Create the parent
$obj_john = $obj_store->createEntity();
Expand Down
2 changes: 1 addition & 1 deletion examples/auto_insert_keys.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
require_once('boilerplate.php');

$obj_store = new GDS\Store($obj_gateway, 'Temperatures');
$obj_store = new GDS\Store('Temperatures', $obj_gateway);

// Delete ALL
// $obj_store->delete($obj_store->fetchAll());
Expand Down
13 changes: 13 additions & 0 deletions examples/boilerplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,25 @@

require_once('Book.php');

// ============================================================================
// ============================================================================
// IMPORTANT - examples using this file operate on the remote Google API client
// ============================================================================
// ============================================================================

// We'll need a Google_Client, use our convenience method
$obj_client = GDS\Gateway\GoogleAPIClient::createGoogleClient(GDS_APP_NAME, GDS_SERVICE_ACCOUNT_NAME, GDS_KEY_FILE_PATH);

// Gateway requires a Google_Client and Dataset ID
$obj_gateway = new GDS\Gateway\GoogleAPIClient($obj_client, GDS_DATASET_ID);

// Alternative native gateway, auto-detect dataset. Should work in dev or live AppEngine
// But not in scripts.
$obj_gateway = new GDS\Gateway\ProtoBuf();

// ============================================================================
// ============================================================================

// Define our Model Schema
$obj_book_schema = (new GDS\Schema('Book'))
->addString('title')
Expand Down
2 changes: 1 addition & 1 deletion examples/datetime_binding.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
->addDatetime('due', TRUE);

// Store requires a Gateway and Schema
$obj_task_store = new GDS\Store($obj_gateway, $obj_task_schema);
$obj_task_store = new GDS\Store($obj_task_schema, $obj_gateway);

// Insert some data, with datetime binding
$obj_task_1 = $obj_task_store->createEntity([
Expand Down
2 changes: 1 addition & 1 deletion examples/dynamic_schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
require_once('boilerplate.php');

$obj_store = new GDS\Store($obj_gateway, 'Friend');
$obj_store = new GDS\Store('Friend', $obj_gateway);

// So now create a simple Model object
$obj_charlie = new GDS\Entity();
Expand Down
2 changes: 1 addition & 1 deletion examples/fetch.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
describeResult($obj_book);
}

$obj_store = new GDS\Store($obj_gateway, 'Contact');
$obj_store = new GDS\Store('Contact', $obj_gateway);
$arr_contacts = $obj_store->fetchByNames(['tom@docnet.nu', 'beermonster@gmail.com']);
foreach($arr_contacts as $obj_contact) {
echo " Found: {$obj_contact->first_name}, {$obj_contact->last_name}", PHP_EOL;
Expand Down
2 changes: 1 addition & 1 deletion examples/list_create.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
->addStringList('tags', TRUE);

// Configure the Store
$obj_store = new GDS\Store($obj_gateway, $obj_contact_schema);
$obj_store = new GDS\Store($obj_contact_schema, $obj_gateway);

// Create 1
$obj_contact1 = $obj_store->createEntity([
Expand Down
2 changes: 1 addition & 1 deletion examples/list_fetch.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
->addStringList('tags', TRUE);

// Configure the Store
$obj_store = new GDS\Store($obj_gateway, $obj_contact_schema);
$obj_store = new GDS\Store($obj_contact_schema, $obj_gateway);

// A couple of tests
show($obj_store->fetchAll("SELECT * FROM Contact_v1 WHERE tags = 'newsletter' AND tags = 'customer'"));
Expand Down
2 changes: 1 addition & 1 deletion examples/simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
$obj_gateway = new GDS\Gateway\GoogleAPIClient($obj_client, GDS_DATASET_ID);

// Store requires a Gateway and Kind
$obj_book_store = new GDS\Store($obj_gateway, 'Book');
$obj_book_store = new GDS\Store('Book', $obj_gateway);

// Fetch a record
$obj_book = $obj_book_store->fetchOne();
Expand Down
16 changes: 16 additions & 0 deletions src/GDS/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/
namespace GDS;
use GDS\Property\Geopoint;

/**
* Map between Google Entity and GDS Entity data/objects
Expand Down Expand Up @@ -77,6 +78,10 @@ protected function determineDynamicType($mix_value)
$int_dynamic_type = Schema::PROPERTY_DATETIME;
break;
}
if($mix_value instanceof Geopoint) {
$int_dynamic_type = Schema::PROPERTY_GEOPOINT;
break;
}
$int_dynamic_type = Schema::PROPERTY_STRING;
if(method_exists($mix_value, '__toString')) {
$mix_value = $mix_value->__toString();
Expand Down Expand Up @@ -143,6 +148,9 @@ protected function extractPropertyValue($int_type, $obj_property)
case Schema::PROPERTY_BOOLEAN:
return $obj_property->getBooleanValue();

case Schema::PROPERTY_GEOPOINT:
return $this->extractGeopointValue($obj_property);

case Schema::PROPERTY_STRING_LIST:
return $this->extractStringListValue($obj_property);

Expand Down Expand Up @@ -177,6 +185,14 @@ abstract protected function extractDatetimeValue($obj_property);
*/
abstract protected function extractStringListValue($obj_property);

/**
* Extract a Geopoint value
*
* @param $obj_property
* @return Geopoint
*/
abstract protected function extractGeopointValue($obj_property);

/**
* Map a single result out of the Raw response data array FROM Google TO a GDS Entity
*
Expand Down
17 changes: 17 additions & 0 deletions src/GDS/Mapper/GoogleAPIClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
namespace GDS\Mapper;
use GDS\Entity;
use GDS\Property\Geopoint;
use GDS\Schema;

/**
Expand Down Expand Up @@ -105,6 +106,10 @@ protected function createProperty(array $arr_field_def, $mix_value)
$obj_property->setBooleanValue((bool)$mix_value);
break;

case Schema::PROPERTY_GEOPOINT:
throw new \RuntimeException('Geopoint properties not supported over JSON API');
break;

case Schema::PROPERTY_STRING_LIST:
$obj_property->setIndexed(null); // Ensure we only index the values, not the list
$arr_values = [];
Expand Down Expand Up @@ -322,6 +327,18 @@ protected function extractStringListValue($obj_property)
return null;
}

/**
* Extract a Geopoint value (lat/lon pair)
*
* @param $obj_property
* @return Geopoint
* @throws \Exception
*/
protected function extractGeopointValue($obj_property)
{
throw new \Exception("Geopoint data not supported with JSON API");
}

/**
* Auto detect & extract a value
*
Expand Down
20 changes: 20 additions & 0 deletions src/GDS/Mapper/ProtoBuf.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace GDS\Mapper;
use GDS\Entity;
use GDS\KeyInterface;
use GDS\Property\Geopoint;
use GDS\Schema;
use google\appengine\datastore\v4\EntityResult;
use google\appengine\datastore\v4\Key;
Expand Down Expand Up @@ -233,6 +234,10 @@ private function configureGooglePropertyValue(Value $obj_val, array $arr_field_d
$obj_val->setBooleanValue((bool)$mix_value);
break;

case Schema::PROPERTY_GEOPOINT:
$obj_val->mutableGeoPointValue()->setLatitude($mix_value[0])->setLongitude($mix_value[1]);
break;

case Schema::PROPERTY_STRING_LIST:
$obj_val->clearIndexed(); // Ensure we only index the values, not the list
foreach ((array)$mix_value as $str) {
Expand Down Expand Up @@ -278,6 +283,18 @@ protected function extractStringListValue($obj_property)
return null;
}

/**
* Extract a Geopoint value (lat/lon pair)
*
* @param \google\appengine\datastore\v4\Value $obj_property
* @return Geopoint
*/
protected function extractGeopointValue($obj_property)
{
$obj_gp_value = $obj_property->getGeoPointValue();
return new Geopoint($obj_gp_value->getLatitude(), $obj_gp_value->getLongitude());
}

/**
* Auto detect & extract a value
*
Expand All @@ -303,6 +320,9 @@ protected function extractAutoDetectValue($obj_property)
if($obj_property->hasBooleanValue()) {
return $obj_property->getBooleanValue();
}
if($obj_property->hasGeoPointValue()) {
return $this->extractGeopointValue($obj_property);
}
if($obj_property->getListValueSize() > 0) {
return $this->extractStringListValue($obj_property);
}
Expand Down
Loading

0 comments on commit 2039923

Please sign in to comment.