Skip to content

Commit

Permalink
Merge branch 'datastore-api-v1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Walder committed Sep 21, 2016
2 parents 3cfdfc5 + 4e0f817 commit 4ccfa37
Show file tree
Hide file tree
Showing 30 changed files with 2,743 additions and 1,430 deletions.
87 changes: 52 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[![Build Status](https://api.travis-ci.org/tomwalder/php-gds.svg)](https://travis-ci.org/tomwalder/php-gds)
[![Coverage Status](https://coveralls.io/repos/tomwalder/php-gds/badge.svg)](https://coveralls.io/r/tomwalder/php-gds)
[![Coverage Status](https://coveralls.io/repos/github/tomwalder/php-gds/badge.svg)](https://coveralls.io/github/tomwalder/php-gds)

# Google Cloud Datastore Library for PHP #

Library **VERSION 3**, September 2016

[Google Cloud Datastore](https://cloud.google.com/datastore/) is a great NoSQL solution (hosted, scalable, free up to a point), but it can be tricky (i.e. there's lots of code glue needed) to get even the "Hello World" of data persistence up and running in PHP.

This library is intended to make it easier for you to get started with and to use Datastore in your applications.
Expand All @@ -11,16 +13,15 @@ This library is intended to make it easier for you to get started with and to us

Google are turning down the older versions of the REST API. Version v1beta2 and v1beta3 are being turned off on 30th September 2016.

* If you are using this library on App Engine, and using the default `Protobuf` gateway then NO CHANGES ARE NEEDED.
* If you are using this library anywhere else, like Compute Engine, and you are using the `GoogleAPIClient` gateway, then you will need to upgrade to version 3.0

**FOR [DATASTORE API V1](https://cloud.google.com/datastore/release-notes) SUPPORT, SEE THE [3.0 ALPHA BRANCH HERE](https://github.com/tomwalder/php-gds/tree/datastore-api-v1)**
* If you are using this library on App Engine, and using the default `Protobuf` gateway then NO CHANGES ARE NEEDED. Version 2.x or 3.x are both supported.
* If you are using this library anywhere else, like Compute Engine, and you are using the `GoogleAPIClient` gateway (version 2.x), then you will need to upgrade to version 3.x

## Table of Contents ##

- [Examples](#examples)
- [New in 2.0](#new-in-version-20)
- [Getting Started](#getting-started)
- [New in version 3.0](#new-in-version-20): [Datastore REST API v1 (Sep 2016)](#using-the-datastore-rest-api-v1-sep-2016)
- [Changes in version 2.0](#changes-in-version-20)
- [Getting Started](#getting-started) including installation with Composer
- [Defining Your Model](#defining-your-model)
- [Creating Records](#creating-records)
- [Geopoint Support](#geopoint)
Expand Down Expand Up @@ -71,40 +72,52 @@ foreach($obj_store->fetchAll() as $obj_book) {
### More about the Examples ###

These initial examples assume you are either running a Google AppEngine application or in a local AppEngine dev environment.
In both of these cases, we can auto detect the **dataset** and use the default ***Protocol Buffer Gateway*** (new in 2.0).
In both of these cases, we can auto detect the **dataset** and use the default ***Protocol Buffer Gateway***.

We use a `GDS\Store` to read and write `GDS\Entity` objects to and from Datastore.

These examples use the generic `GDS\Entity` class with a dynamic Schema. See [Defining Your Model](#defining-your-model) below for more details on custom Schemas and indexed fields.

Check out the [examples](examples/) folder for many more and fuller code samples.

### Using the Google PHP API and the JSON Datastore API ###
### Demo Application ###

A little more configuration is required if you want or need to use the JSON API instead of Protocol Buffers.
A simple guest book application

The Store needs a `GDS\Gateway` to talk to Google and the gateway needs a `Google_Client` for authentication. You will need to include the [Google Client LIbrary for PHP](https://developers.google.com/api-client-library/php/) as well as create credentials for a service account in order to build the `Google_Client` properly.
Application: http://php-gds-demo.appspot.com/

Code: https://github.com/tomwalder/php-gds-demo

```php
$obj_client = GDS\Gateway\GoogleAPIClient::createClientFromJson('/path/to/your/service.json');
$obj_gateway = new GDS\Gateway\GoogleAPIClient($obj_client, PROJECT_ID);
$obj_book_store = new GDS\Store('sBook', $obj_gateway);
```
## New in Version 3.0 ##

You can download a service account JSON file from the Google Cloud Console `API Manager > Credentials`.
* Support for the new **Datastore API, v1 - via REST** (gRPC to come)
* Removal of support for the old 1.x series "PHP Google API Client"
* **GeoPoint data is now supported over the REST API** v1 as well as ProtoBuf

### Demo Application ###
### Using the Datastore REST API v1 (Sep 2016) ###

A simple guest book application
The Datastore REST API v1 went Generally Available (GA) in 2016. The previous REST API will be deprecated after September 2016.

Application: http://php-gds-demo.appspot.com/
If you are running PHP-GDS from somewhere other than App Engine, you need to use the REST API v1.

Code: https://github.com/tomwalder/php-gds-demo
You just have to pass an instance of the RESTv1 gateway into your Store objects on construction.

You might need to set an environment variable with the path to your JSON credentials file first.

```php
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/credentials.json');

// A regular Store, but with a custom Gateway
$obj_book_store = new GDS\Store('Book', new \GDS\Gateway\RESTv1(PROJECT_ID));
```

## New in Version 2.0 ##
You can find out more about the auth system here: [Google Auth Library for PHP](https://github.com/google/google-auth-library-php)

New features in 2.0 include
You can download a service account JSON file from the Google Cloud Console `API Manager > Credentials`.

## Changes in Version 2.0 ##

Features in 2.0 included
* **Faster** - use of Google Protocol Buffer allows faster, low-level access to Datastore
* **Easier to use** - sensible defaults and auto-detection for AppEngine environments
* **Less dependencies** - no need for the Google PHP API Client, unless running remote or from non-AppEngine environments
Expand All @@ -117,6 +130,12 @@ New features in 2.0 include

### Backwards Compatibility ###

#### v3 over v2 ####

The REST API v1 implementation now follows the same datetime response formats at the ProtoBuf API. (Y-m-d H:i:s).

#### v2 over v1 ####

The library is *almost* fully backwards compatible. And in fact, the main operations of the `GDS\Store` class are identical.

There is one BC-break in 2.0 - the re-ordering of construction parameters for the `GDS\Store` class.
Expand All @@ -136,19 +155,18 @@ Are you sitting comfortably? Before we begin, you will need:
- a Project to work on with the "Google Cloud Datastore API" turned ON [Google Developer Console](https://console.developers.google.com/)

If you want to use the JSON API from remote or non-App Engine environments, you will also need
- a "Service account" and **either**
- **(recommended, simpler)** the JSON service key file, downloadable from the Developer Console
- or a P12 key file for that service account [Service Accounts](https://developers.google.com/accounts/docs/OAuth2#serviceaccount) along with the service account name
- Application default credentials **OR**
- a "Service account" and the JSON service key file, downloadable from the Developer Console

### Composer, Dependencies ###

To install using Composer, use this require line, for production
To install using Composer, use this require line **alpha series**

`"tomwalder/php-gds": "v2.1.1"`
`"tomwalder/php-gds": "v3.*"`

For older, version 1 series
For older, version 2 series

`"tomwalder/php-gds": "v1.2.1"`
`"tomwalder/php-gds": "v2.*"`

and for bleeding-edge features, dev-master

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

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

Expand Down Expand Up @@ -350,9 +368,8 @@ This library supports namespaces, and they are be configured per `Gateway` insta

```php
// Create a store for a particular customer or 'application namespace'
$obj_client = GDS\Gateway\GoogleAPIClient::createClientFromJson('/path/to/your/service.json');
$obj_namespaced_gateway = new GDS\Gateway($obj_client, PROJECT_ID, 'customer-namespace');
$obj_namespaced_book_store = new BookStore($obj_namespaced_gateway);
$obj_gateway = new \GDS\Gateway\RESTv1('project-id', 'namespace');
$obj_store = new \GDS\Store('Book', $obj_gateway);
```

Further examples are included in the examples folder.
Expand Down Expand Up @@ -438,7 +455,7 @@ and between local and live environments.
```php
// Local and Remote Gateways
$obj_gateway_local = new \GDS\Gateway\ProtoBuf();
$obj_gateway_remote = new \GDS\Gateway\GoogleAPIClient($obj_google_client);
$obj_gateway_remote = new \GDS\Gateway\RESTv1('project-name');

// Grab some books from local
$arr_books = (new \GDS\Store('Book', $obj_gateway_local))->fetchPage(20);
Expand Down
9 changes: 3 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@
}
],
"require": {
"php": ">=5.5.0"
},
"suggest": {
"google/apiclient": "Allows you to use the JSON API Gateway/Datastore endpoints. Tested with 1.1.7"
"php": ">=5.5.0",
"google/auth": "0.10"
},
"require-dev": {
"google/appengine-php-sdk": ">=1.9.22",
"phpunit/phpunit": "~4.8",
"satooshi/php-coveralls": "dev-master",
"google/apiclient": "1.1.7"
"satooshi/php-coveralls": "dev-master"
},
"autoload": {
"classmap": [
Expand Down
2 changes: 0 additions & 2 deletions examples/_includes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
require_once('../src/GDS/Store.php');
require_once('../src/GDS/Gateway.php');
require_once('../src/GDS/Gateway/ProtoBuf.php');
require_once('../src/GDS/Gateway/GoogleAPIClient.php');
require_once('../src/GDS/Mapper.php');
require_once('../src/GDS/Mapper/ProtoBuf.php');
require_once('../src/GDS/Mapper/ProtoBufGQLParser.php');
require_once('../src/GDS/Mapper/GoogleAPIClient.php');
require_once('../src/GDS/Exception/GQL.php');
6 changes: 0 additions & 6 deletions examples/boilerplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
// ============================================================================
// ============================================================================

// 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();
Expand Down
2 changes: 0 additions & 2 deletions examples/config/.gitignore

This file was deleted.

10 changes: 0 additions & 10 deletions examples/config/_config.php

This file was deleted.

15 changes: 0 additions & 15 deletions examples/config/setup.php

This file was deleted.

6 changes: 2 additions & 4 deletions examples/list_create.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
* @author Tom Walder <tom@docnet.nu>
*/
require_once('../vendor/autoload.php');
require_once('config/setup.php');

// We'll need a Google_Client, use our convenience method
$obj_google_client = GDS\Gateway\GoogleAPIClient::createGoogleClient(GDS_APP_NAME, GDS_SERVICE_ACCOUNT_NAME, GDS_KEY_FILE_PATH);
$obj_gateway = new GDS\Gateway\GoogleAPIClient($obj_google_client, GDS_DATASET_ID); // Optionally, namespace
// We'll need a Gateway (for REST API usage, NOT on App Engine)
$obj_gateway = new \GDS\Gateway\RESTv1('my-app-id-here');

// Define the model on-the-fly
$obj_contact_schema = (new GDS\Schema('Contact'))
Expand Down
6 changes: 1 addition & 5 deletions examples/list_fetch.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@
require_once('../vendor/autoload.php');
require_once('config/setup.php');

// We'll need a Google_Client, use our convenience method
$obj_google_client = GDS\Gateway\GoogleAPIClient::createGoogleClient(GDS_APP_NAME, GDS_SERVICE_ACCOUNT_NAME, GDS_KEY_FILE_PATH);
$obj_gateway = new GDS\Gateway\GoogleAPIClient($obj_google_client, GDS_DATASET_ID); // Optionally, namespace

// Define the model on-the-fly
$obj_contact_schema = (new GDS\Schema('Contact'))
->addString('first_name')
->addString('last_name')
->addStringList('tags', TRUE);

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

// A couple of tests
show($obj_store->fetchAll("SELECT * FROM Contact_v1 WHERE tags = 'newsletter' AND tags = 'customer'"));
Expand Down
9 changes: 1 addition & 8 deletions examples/simple.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,9 @@
* @author Tom Walder <tom@docnet.nu>
*/
require_once('../vendor/autoload.php');
require_once('config/setup.php');

// 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);

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

// Fetch a record
$obj_book = $obj_book_store->fetchOne();
Expand Down
3 changes: 1 addition & 2 deletions examples/simple/create_many.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

// Alternative Gateway (remote JSON API)
// Download your service JSON file from the Google Developer Console
// $obj_client = \GDS\Gateway\GoogleAPIClient::createClientFromJson('/path/to/your/service.json');
// $obj_gateway = new \GDS\Gateway\GoogleAPIClient($obj_client, 'your-app-id');
// $obj_gateway = new \GDS\Gateway\RESTv1('your-app-id');
// $obj_store = new \GDS\Store('Book', $obj_gateway);

// Create some Entity objects
Expand Down
3 changes: 1 addition & 2 deletions examples/simple/create_one.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

// Alternative Gateway (remote JSON API)
// Download your service JSON file from the Google Developer Console
// $obj_client = \GDS\Gateway\GoogleAPIClient::createClientFromJson('/path/to/your/service.json');
// $obj_gateway = new \GDS\Gateway\GoogleAPIClient($obj_client, 'your-app-id');
// $obj_gateway = new \GDS\Gateway\RESTv1('your-app-id');
// $obj_store = new \GDS\Store('Book', $obj_gateway);

// Create a simple Entity object
Expand Down
3 changes: 1 addition & 2 deletions examples/simple/create_one_array_syntax.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

// Alternative Gateway (remote JSON API)
// Download your service JSON file from the Google Developer Console
// $obj_client = \GDS\Gateway\GoogleAPIClient::createClientFromJson('/path/to/your/service.json');
// $obj_gateway = new \GDS\Gateway\GoogleAPIClient($obj_client, 'your-app-id');
// $obj_gateway = new \GDS\Gateway\RESTv1('your-app-id');
// $obj_store = new \GDS\Store('Book', $obj_gateway);

// Create a simple Entity object
Expand Down
5 changes: 5 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@
<logging>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
</phpunit>
Loading

0 comments on commit 4ccfa37

Please sign in to comment.