From be4930a373845b69956759a5c6c9fb0084e10de5 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Fri, 12 Jan 2018 10:55:00 -0800 Subject: [PATCH] Move datastore samples. (#552) --- README.md | 2 +- circle.yml | 1 - datastore/README.md | 93 +- datastore/concepts.js | 1293 ---------------------- datastore/error.js | 57 - datastore/package.json | 58 - datastore/quickstart.js | 53 - datastore/system-test/concepts.test.js | 148 --- datastore/system-test/error.test.js | 29 - datastore/system-test/index.yaml | 36 - datastore/system-test/quickstart.test.js | 73 -- datastore/system-test/tasks.test.js | 73 -- datastore/tasks.js | 198 ---- 13 files changed, 5 insertions(+), 2109 deletions(-) delete mode 100644 datastore/concepts.js delete mode 100644 datastore/error.js delete mode 100644 datastore/package.json delete mode 100644 datastore/quickstart.js delete mode 100644 datastore/system-test/concepts.test.js delete mode 100644 datastore/system-test/error.test.js delete mode 100644 datastore/system-test/index.yaml delete mode 100644 datastore/system-test/quickstart.test.js delete mode 100644 datastore/system-test/tasks.test.js delete mode 100644 datastore/tasks.js diff --git a/README.md b/README.md index 4361d4daa8..330e594c74 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ automatic scaling, high performance, and ease of application development. View the [Cloud Datastore Node.js samples][datastore_samples]. [datastore_docs]: https://cloud.google.com/datastore/docs/ -[datastore_samples]: datastore +[datastore_samples]: https://github.com/googleapis/nodejs-datastore/tree/master/samples #### Google Cloud Storage diff --git a/circle.yml b/circle.yml index 780f05a5d5..c6839c0609 100644 --- a/circle.yml +++ b/circle.yml @@ -101,7 +101,6 @@ deployment: - node scripts/build "appengine/pubsub" - export GCP_QUEUE=nodejs-test-queue-do-not-delete; node scripts/build "cloudtasks" - node scripts/build "containerengine/hello-world" - - node scripts/build "datastore" - node scripts/build "debugger" - node scripts/build "endpoints/getting-started" # TODO(ace-n): Get this working again diff --git a/datastore/README.md b/datastore/README.md index f1cbd55934..09f7a16251 100644 --- a/datastore/README.md +++ b/datastore/README.md @@ -1,90 +1,5 @@ -Google Cloud Platform logo +Samples for the [Datastore API Node.js Client][client] have moved to +[github.com/googleapis/nodejs-datastore/tree/master/samples/][samples]. -# Google Cloud Datastore Node.js Samples - -[![Build](https://storage.googleapis.com/cloud-docs-samples-badges/GoogleCloudPlatform/nodejs-docs-samples/nodejs-docs-samples-datastore.svg)]() - -[Cloud Datastore](https://cloud.google.com/datastore/docs) is a NoSQL document database built for automatic scaling, high performance, and ease of application development. While the Cloud Datastore interface has many of the same features as traditional databases, as a NoSQL database it differs from them in the way it describes relationships between data objects. - -## Table of Contents - -* [Setup](#setup) -* [Samples](#samples) - * [Tasks](#tasks) - * [Concepts](#concepts) - * [Errors and Error Handling](#errors-and-error-handling) -* [Running the tests](#running-the-tests) - -## Setup - -1. Read [Prerequisites][prereq] and [How to run a sample][run] first. -1. Install dependencies: - - With **npm**: - - npm install - - With **yarn**: - - yarn install - -[prereq]: ../README.md#prerequisites -[run]: ../README.md#how-to-run-a-sample - -## Samples - -### Tasks - -View the [documentation][tasks_0_docs] or the [source code][tasks_0_code]. - -__Usage:__ `node tasks.js --help` - -``` -Commands: - new Adds a task with a description . - done Marks the specified task as done. - list Lists all tasks ordered by creation time. - delete Deletes a task. - -Options: - --version Show version number [boolean] - --help Show help [boolean] - -Examples: - node tasks.js new "Buy milk" Adds a task with description "Buy milk". - node tasks.js done 12345 Marks task 12345 as Done. - node tasks.js list Lists all tasks ordered by creation time - node tasks.js delete 12345 Deletes task 12345. - -For more information, see https://cloud.google.com/datastore/docs -``` - -[tasks_0_docs]: https://cloud.google.com/datastore/docs/datastore-api-tutorial -[tasks_0_code]: tasks.js - -### Concepts - -View the [documentation][concepts_1_docs] or the [source code][concepts_1_code].[concepts_1_docs]: https://cloud.google.com/datastore/docs/concepts/entities -[concepts_1_code]: concepts.js - -### Errors and Error Handling - -View the [documentation][error_2_docs] or the [source code][error_2_code]. - -__Usage:__ `node error.js` -[error_2_docs]: https://cloud.google.com/datastore/docs/concepts/errors -[error_2_code]: error.js - -## Running the tests - -1. Set the **GCLOUD_PROJECT** and **GOOGLE_APPLICATION_CREDENTIALS** environment variables. - -1. Run the tests: - - With **npm**: - - npm test - - With **yarn**: - - yarn test +[client]: https://github.com/googleapis/nodejs-datastore +[samples]: https://github.com/googleapis/nodejs-datastore/tree/master/samples diff --git a/datastore/concepts.js b/datastore/concepts.js deleted file mode 100644 index 453457b6b7..0000000000 --- a/datastore/concepts.js +++ /dev/null @@ -1,1293 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const sinon = require('sinon'); - -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -const Datastore = require('@google-cloud/datastore'); - -function makeStub () { - return sinon.stub().returns(Promise.resolve([])); -} - -// This mock is used in the documentation snippets. -let datastore = { - delete: makeStub(), - get: makeStub(), - insert: makeStub(), - key: makeStub(), - update: makeStub(), - upsert: makeStub(), - runQuery: sinon.stub().returns(Promise.resolve([[]])), - save: makeStub() -}; - -class TestHelper { - constructor (projectId) { - const options = { - projectId: projectId - }; - this.datastore = Datastore(options); - } -} - -class Entity extends TestHelper { - constructor (projectId) { - super(projectId); - // To create the keys, we have to use this instance of Datastore. - datastore.key = this.datastore.key; - - this.incompleteKey = this.getIncompleteKey(); - this.namedKey = this.getNamedKey(); - this.keyWithParent = this.getKeyWithParent(); - this.keyWithMultiLevelParent = this.getKeyWithMultiLevelParent(); - } - - getIncompleteKey () { - // [START incomplete_key] - const taskKey = datastore.key('Task'); - // [END incomplete_key] - - return taskKey; - } - - getNamedKey () { - // [START named_key] - const taskKey = datastore.key([ - 'Task', - 'sampleTask' - ]); - // [END named_key] - - return taskKey; - } - - getKeyWithParent () { - // [START key_with_parent] - const taskKey = datastore.key([ - 'TaskList', - 'default', - 'Task', - 'sampleTask' - ]); - // [END key_with_parent] - - return taskKey; - } - - getKeyWithMultiLevelParent () { - // [START key_with_multilevel_parent] - const taskKey = datastore.key([ - 'User', - 'alice', - 'TaskList', - 'default', - 'Task', - 'sampleTask' - ]); - // [END key_with_multilevel_parent] - - return taskKey; - } - - getTask () { - // [START basic_entity] - const task = { - category: 'Personal', - done: false, - priority: 4, - description: 'Learn Cloud Datastore' - }; - // [END basic_entity] - - return task; - } - - testIncompleteKey (t) { - t.plan(0); - return this.datastore.save({ - key: this.incompleteKey, - data: {} - }); - } - - testNamedKey (t) { - t.plan(0); - return this.datastore.save({ - key: this.namedKey, - data: {} - }); - } - - testKeyWithParent (t) { - t.plan(0); - return this.datastore.save({ - key: this.keyWithParent, - data: {} - }); - } - - testKeyWithMultiLevelParent (t) { - t.plan(0); - return this.datastore.save({ - key: this.keyWithMultiLevelParent, - data: {} - }); - } - - testEntityWithParent (t) { - t.plan(0); - const taskKey = this.keyWithParent; - - // [START entity_with_parent] - const task = { - key: taskKey, - data: { - category: 'Personal', - done: false, - priority: 4, - description: 'Learn Cloud Datastore' - } - }; - // [END entity_with_parent] - - return this.datastore.save(task); - } - - testProperties (t) { - // [START properties] - const task = [ - { - name: 'category', - value: 'Personal' - }, - { - name: 'created', - value: new Date() - }, - { - name: 'done', - value: false - }, - { - name: 'priority', - value: 4 - }, - { - name: 'percent_complete', - value: 10.0 - }, - { - name: 'description', - value: 'Learn Cloud Datastore', - excludeFromIndexes: true - } - ]; - // [END properties] - - return this.datastore.save({ - key: this.incompleteKey, - data: task - }); - } - - testArrayValue (t) { - t.plan(0); - // [START array_value] - const task = { - tags: [ - 'fun', - 'programming' - ], - collaborators: [ - 'alice', - 'bob' - ] - }; - // [END array_value] - - return this.datastore.save({ - key: this.incompleteKey, - data: task - }); - } - - testBasicEntity (t) { - t.plan(0); - return this.datastore.save({ - key: this.getIncompleteKey(), - data: this.getTask() - }); - } - - testUpsert (t) { - t.plan(0); - const taskKey = this.getIncompleteKey(); - const task = this.getTask(); - - // [START upsert] - const entity = { - key: taskKey, - data: task - }; - - datastore.upsert(entity) - .then(() => { - // Task inserted successfully. - }); - // [END upsert] - - return this.datastore.upsert({ - key: this.datastore.key(['Task', 1]), - data: task - }); - } - - testInsert (t) { - t.plan(0); - const taskKey = this.getIncompleteKey(); - const task = this.getTask(); - - // [START insert] - const entity = { - key: taskKey, - data: task - }; - - datastore.insert(entity) - .then(() => { - // Task inserted successfully. - }); - // [END insert] - - return this.datastore.save({ - method: 'insert', - key: taskKey, - data: task - }); - } - - testLookup (t) { - t.plan(0); - const taskKey = this.getIncompleteKey(); - - // [START lookup] - datastore.get(taskKey) - .then((results) => { - // Task found. - const entity = results[0]; - - // entity = { - // category: 'Personal', - // done: false, - // priority: 4, - // description: 'Learn Cloud Datastore' - // }; - console.log(entity); - }); - // [END lookup] - - return this.datastore.save({ - method: 'insert', - key: taskKey, - data: {} - }).then(() => this.datastore.get(taskKey)); - } - - testUpdate (t) { - t.plan(0); - const taskKey = this.getIncompleteKey(); - const task = this.getTask(); - - // [START update] - const entity = { - key: taskKey, - data: task - }; - - datastore.update(entity) - .then(() => { - // Task updated successfully. - }); - // [END update] - - return this.datastore.save({ - method: 'insert', - key: taskKey, - data: {} - }).then(() => this.datastore.update({ key: taskKey, data: task })); - } - - testDelete (t) { - t.plan(0); - const taskKey = this.getIncompleteKey(); - - // [START delete] - datastore.delete(taskKey) - .then(() => { - // Task deleted successfully. - }); - // [END delete] - - return this.datastore.save({ - method: 'insert', - key: taskKey, - data: {} - }).then(() => this.datastore.delete(taskKey)); - } - - testBatchUpsert (t) { - const taskKey1 = this.datastore.key(['Task', 1]); - const taskKey2 = this.datastore.key(['Task', 2]); - - const task1 = { - category: 'Personal', - done: false, - priority: 4, - description: 'Learn Cloud Datastore' - }; - - const task2 = { - category: 'Work', - done: false, - priority: 8, - description: 'Integrate Cloud Datastore' - }; - - // [START batch_upsert] - const entities = [ - { - key: taskKey1, - data: task1 - }, - { - key: taskKey2, - data: task2 - } - ]; - - datastore.upsert(entities) - .then(() => { - // Tasks inserted successfully. - }); - // [END batch_upsert] - - return this.datastore.upsert([ - { - key: taskKey1, - data: task1 - }, - { - key: taskKey2, - data: task2 - } - ]); - } - - testBatchLookup (t) { - t.plan(0); - const taskKey1 = this.datastore.key(['Task', 1]); - const taskKey2 = this.datastore.key(['Task', 2]); - - // [START batch_lookup] - const keys = [taskKey1, taskKey2]; - - datastore.get(keys) - .then((results) => { - // Tasks retrieved successfully. - const tasks = results[0]; - - console.log(tasks); - }); - // [END batch_lookup] - - return this.datastore.get([taskKey1, taskKey2]); - } - - testBatchDelete (t) { - t.plan(0); - const taskKey1 = this.datastore.key(['Task', 1]); - const taskKey2 = this.datastore.key(['Task', 2]); - - // [START batch_delete] - const keys = [taskKey1, taskKey2]; - - datastore.delete(keys) - .then(() => { - // Tasks deleted successfully. - }); - // [END batch_delete] - - return this.datastore.delete([taskKey1, taskKey2]); - } -} - -class Index extends TestHelper { - testUnindexedPropertyQuery (t) { - t.plan(0); - const datastore = this.datastore; - - // [START unindexed_property_query] - const query = datastore.createQuery('Task') - .filter('description', '=', 'A task description.'); - // [END unindexed_property_query] - - return this.datastore.runQuery(query); - } - - testExplodingProperties (t) { - const original = datastore.key; - datastore.key = this.datastore.key; - - // [START exploding_properties] - const task = { - method: 'insert', - key: datastore.key('Task'), - data: { - tags: [ - 'fun', - 'programming', - 'learn' - ], - collaborators: [ - 'alice', - 'bob', - 'charlie' - ], - created: new Date() - } - }; - // [END exploding_properties] - - datastore.key = original; - - return this.datastore.save(task) - .then(() => { - t.truthy(task.key); - t.truthy(task.key.id); - }); - } -} - -class Metadata extends TestHelper { - testNamespaceRunQuery (t) { - const datastore = this.datastore; - - const startNamespace = 'Animals'; - const endNamespace = 'Zoos'; - - return datastore.save({ - key: datastore.key({ - namespace: 'Animals', - path: ['Ant', 1] - }), - data: {} - }) - .then(() => { - // [START namespace_run_query] - function runNamespaceQuery (startNamespace, endNamespace) { - const startKey = datastore.key(['__namespace__', startNamespace]); - const endKey = datastore.key(['__namespace__', endNamespace]); - - const query = datastore.createQuery('__namespace__') - .select('__key__') - .filter('__key__', '>=', startKey) - .filter('__key__', '<', endKey); - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - const namespaces = entities.map((entity) => entity[datastore.KEY].name); - - console.log('Namespaces:'); - namespaces.forEach((namespace) => console.log(namespace)); - - return namespaces; - }); - } - // [END namespace_run_query] - - return runNamespaceQuery(startNamespace, endNamespace); - }) - .then((namespaces) => { - t.true(namespaces.includes('Animals')); - }); - } - - testKindRunQuery (t) { - const datastore = this.datastore; - - // [START kind_run_query] - function runKindQuery () { - const query = datastore.createQuery('__kind__') - .select('__key__'); - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - const kinds = entities.map((entity) => entity[datastore.KEY].name); - - console.log('Kinds:'); - kinds.forEach((kind) => console.log(kind)); - - return kinds; - }); - } - // [END kind_run_query] - - return runKindQuery() - .then((kinds) => { - t.true(kinds.includes('Account')); - }); - } - - testPropertyRunQuery (t) { - const datastore = this.datastore; - - // [START property_run_query] - function runPropertyQuery () { - const query = datastore.createQuery('__property__') - .select('__key__'); - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - const propertiesByKind = {}; - - entities.forEach((entity) => { - const key = entity[datastore.KEY]; - const kind = key.path[1]; - const property = key.path[3]; - - propertiesByKind[kind] = propertiesByKind[kind] || []; - propertiesByKind[kind].push(property); - }); - - console.log('Properties by Kind:'); - for (let key in propertiesByKind) { - console.log(key, propertiesByKind[key]); - } - - return propertiesByKind; - }); - } - // [END property_run_query] - - return runPropertyQuery() - .then((propertiesByKind) => { - t.deepEqual(propertiesByKind.Account, ['balance']); - }); - } - - testPropertyByKindRunQuery (t) { - const datastore = this.datastore; - - // [START property_by_kind_run_query] - function runPropertyByKindQuery () { - const ancestorKey = datastore.key(['__kind__', 'Account']); - - const query = datastore.createQuery('__property__') - .hasAncestor(ancestorKey); - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - - const representationsByProperty = {}; - - entities.forEach((entity) => { - const key = entity[datastore.KEY]; - const propertyName = key.name; - const propertyType = entity.property_representation; - - representationsByProperty[propertyName] = propertyType; - }); - - console.log('Task property representations:'); - for (let key in representationsByProperty) { - console.log(key, representationsByProperty[key]); - } - - return representationsByProperty; - }); - } - // [END property_by_kind_run_query] - - return runPropertyByKindQuery() - .then((propertiesByKind) => { - t.deepEqual(propertiesByKind, { - balance: ['INT64'] - }); - }); - } -} - -class Query extends TestHelper { - constructor (projectId) { - super(projectId); - - this.basicQuery = this.getBasicQuery(); - this.projectionQuery = this.getProjectionQuery(); - this.ancestorQuery = this.getAncestorQuery(); - } - - getBasicQuery () { - const datastore = this.datastore; - - // [START basic_query] - const query = datastore.createQuery('Task') - .filter('done', '=', false) - .filter('priority', '>=', 4) - .order('priority', { - descending: true - }); - // [END basic_query] - - return query; - } - - getProjectionQuery () { - const datastore = this.datastore; - - // [START projection_query] - const query = datastore.createQuery('Task') - .select(['priority', 'percent_complete']); - // [END projection_query] - - return query; - } - - getAncestorQuery () { - const datastore = this.datastore; - - // [START ancestor_query] - const ancestorKey = datastore.key(['TaskList', 'default']); - - const query = datastore.createQuery('Task') - .hasAncestor(ancestorKey); - // [END ancestor_query] - - return query; - } - - testRunQuery (t) { - t.plan(0); - const query = this.basicQuery; - - // [START run_query] - datastore.runQuery(query) - .then((results) => { - // Task entities found. - const tasks = results[0]; - - console.log('Tasks:'); - tasks.forEach((task) => console.log(task)); - }); - // [END run_query] - - return this.datastore.runQuery(query); - } - - testPropertyFilter (t) { - t.plan(0); - const datastore = this.datastore; - - // [START property_filter] - const query = datastore.createQuery('Task') - .filter('done', '=', false); - // [END property_filter] - - return this.datastore.runQuery(query); - } - - testCompositeFilter (t) { - t.plan(0); - const datastore = this.datastore; - - // [START composite_filter] - const query = datastore.createQuery('Task') - .filter('done', '=', false) - .filter('priority', '=', 4); - // [END composite_filter] - - return this.datastore.runQuery(query); - } - - testKeyFilter (t) { - t.plan(0); - const datastore = this.datastore; - - // [START key_filter] - const query = datastore.createQuery('Task') - .filter('__key__', '>', datastore.key(['Task', 'someTask'])); - // [END key_filter] - - return this.datastore.runQuery(query); - } - - testAscendingSort (t) { - t.plan(0); - const datastore = this.datastore; - - // [START ascending_sort] - const query = datastore.createQuery('Task') - .order('created'); - // [END ascending_sort] - - return this.datastore.runQuery(query); - } - - testDescendingSort (t) { - t.plan(0); - const datastore = this.datastore; - - // [START descending_sort] - const query = datastore.createQuery('Task') - .order('created', { - descending: true - }); - // [END descending_sort] - - return this.datastore.runQuery(query); - } - - testMultiSort (t) { - t.plan(0); - const datastore = this.datastore; - - // [START multi_sort] - const query = datastore.createQuery('Task') - .order('priority', { - descending: true - }) - .order('created'); - // [END multi_sort] - - return this.datastore.runQuery(query); - } - - testKindlessQuery (t) { - t.plan(0); - const datastore = this.datastore; - const lastSeenKey = this.datastore.key(['Task', Date.now()]); - - // [START kindless_query] - const query = datastore.createQuery() - .filter('__key__', '>', lastSeenKey) - .limit(1); - // [END kindless_query] - - return this.datastore.runQuery(query); - } - - testRunQueryProjection () { - const datastore = this.datastore; - const query = this.projectionQuery; - - // [START run_query_projection] - function runProjectionQuery () { - const priorities = []; - const percentCompletes = []; - - return datastore.runQuery(query) - .then((results) => { - const tasks = results[0]; - - tasks.forEach((task) => { - priorities.push(task.priority); - percentCompletes.push(task.percent_complete); - }); - - return { - priorities: priorities, - percentCompletes: percentCompletes - }; - }); - } - // [END run_query_projection] - - return runProjectionQuery(); - } - - testKeysOnlyQuery (t) { - t.plan(0); - const datastore = this.datastore; - - // [START keys_only_query] - const query = datastore.createQuery() - .select('__key__') - .limit(1); - // [END keys_only_query] - - return this.datastore.runQuery(query); - } - - testDistinctQuery (t) { - t.plan(0); - const datastore = this.datastore; - - // [START distinct_query] - const query = datastore.createQuery('Task') - .groupBy(['category', 'priority']) - .order('category') - .order('priority'); - // [END distinct_query] - - return this.datastore.runQuery(query); - } - - testDistinctOnQuery (t) { - t.plan(0); - const datastore = this.datastore; - - // [START distinct_on_query] - const query = datastore.createQuery('Task') - .groupBy('category') - .order('category') - .order('priority'); - // [END distinct_on_query] - - return this.datastore.runQuery(query); - } - - testArrayValueInequalityRange (t) { - t.plan(0); - const datastore = this.datastore; - - // [START array_value_inequality_range] - const query = datastore.createQuery('Task') - .filter('tag', '>', 'learn') - .filter('tag', '<', 'math'); - // [END array_value_inequality_range] - - return this.datastore.runQuery(query); - } - - testArrayValueEquality (t) { - t.plan(0); - const datastore = this.datastore; - - // [START array_value_equality] - const query = datastore.createQuery('Task') - .filter('tag', '=', 'fun') - .filter('tag', '=', 'programming'); - // [END array_value_equality] - - return this.datastore.runQuery(query); - } - - testInequalityRange (t) { - t.plan(0); - const datastore = this.datastore; - - // [START inequality_range] - const query = datastore.createQuery('Task') - .filter('created', '>', new Date('1990-01-01T00:00:00z')) - .filter('created', '<', new Date('2000-12-31T23:59:59z')); - // [END inequality_range] - - return this.datastore.runQuery(query); - } - - testInequalityInvalid () { - const datastore = this.datastore; - - // [START inequality_invalid] - const query = datastore.createQuery('Task') - .filter('priority', '>', 3) - .filter('created', '>', new Date('1990-01-01T00:00:00z')); - // [END inequality_invalid] - - return this.datastore.runQuery(query); - } - - testEqualAndInequalityRange (t) { - t.plan(0); - const datastore = this.datastore; - - // [START equal_and_inequality_range] - const query = datastore.createQuery('Task') - .filter('priority', '=', 4) - .filter('done', '=', false) - .filter('created', '>', new Date('1990-01-01T00:00:00z')) - .filter('created', '<', new Date('2000-12-31T23:59:59z')); - // [END equal_and_inequality_range] - - return this.datastore.runQuery(query); - } - - testInequalitySort (t) { - t.plan(0); - const datastore = this.datastore; - - // [START inequality_sort] - const query = datastore.createQuery('Task') - .filter('priority', '>', 3) - .order('priority') - .order('created'); - // [END inequality_sort] - - return this.datastore.runQuery(query); - } - - testInequalitySortInvalidNotSame () { - const datastore = this.datastore; - - // [START inequality_sort_invalid_not_same] - const query = datastore.createQuery('Task') - .filter('priority', '>', 3) - .order('created'); - // [END inequality_sort_invalid_not_same] - - return this.datastore.runQuery(query); - } - - testInequalitySortInvalidNotFirst (t) { - const datastore = this.datastore; - - // [START inequality_sort_invalid_not_first] - const query = datastore.createQuery('Task') - .filter('priority', '>', 3) - .order('created') - .order('priority'); - // [END inequality_sort_invalid_not_first] - - return this.datastore.runQuery(query); - } - - testLimit (t) { - t.plan(0); - const datastore = this.datastore; - - // [START limit] - const query = datastore.createQuery('Task') - .limit(5); - // [END limit] - - return this.datastore.runQuery(query); - } - - testCursorPaging (t) { - const datastore = this.datastore; - const pageSize = 1; - - // [START cursor_paging] - // By default, google-cloud-node will automatically paginate through all of - // the results that match a query. However, this sample implements manual - // pagination using limits and cursor tokens. - function runPageQuery (pageCursor) { - let query = datastore.createQuery('Task') - .limit(pageSize); - - if (pageCursor) { - query = query.start(pageCursor); - } - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - const info = results[1]; - - if (info.moreResults !== Datastore.NO_MORE_RESULTS) { - // If there are more results to retrieve, the end cursor is - // automatically set on `info`. To get this value directly, access - // the `endCursor` property. - return runPageQuery(info.endCursor) - .then((results) => { - // Concatenate entities - results[0] = entities.concat(results[0]); - return results; - }); - } - - return [entities, info]; - }); - } - // [END cursor_paging] - - return runPageQuery() - .then((results) => { - const entities = results[0]; - t.true(Array.isArray(entities)); - const info = results[1]; - if (!info || !info.endCursor) { - throw new Error('An `info` with an `endCursor` is not present.'); - } - }); - } - - testEventualConsistentQuery (t) { - t.plan(0); - const datastoreMock = datastore; - datastore = this.datastore; - // [START eventual_consistent_query] - const ancestorKey = datastore.key(['TaskList', 'default']); - const query = datastore.createQuery('Task') - .hasAncestor(ancestorKey); - - query.run({ consistency: 'eventual' }); - // [END eventual_consistent_query] - return query.run({ consistency: 'eventual' }) - .then((results) => { - datastore = datastoreMock; - const entities = results[0]; - return entities; - }) - .catch((err) => { - datastore = datastoreMock; - return Promise.reject(err); - }); - } -} - -// [START transactional_update] -function transferFunds (fromKey, toKey, amount) { - const transaction = datastore.transaction(); - - return transaction.run() - .then(() => Promise.all([transaction.get(fromKey), transaction.get(toKey)])) - .then((results) => { - const accounts = results - .map((result) => result[0]); - - accounts[0].balance -= amount; - accounts[1].balance += amount; - - transaction.save([ - { - key: fromKey, - data: accounts[0] - }, - { - key: toKey, - data: accounts[1] - } - ]); - - return transaction.commit(); - }) - .catch(() => transaction.rollback()); -} -// [END transactional_update] - -class Transaction extends TestHelper { - constructor (projectId) { - super(projectId); - this.fromKey = this.datastore.key(['Bank', 1, 'Account', 1]); - this.toKey = this.datastore.key(['Bank', 1, 'Account', 2]); - - this.originalBalance = 100; - this.amountToTransfer = 10; - } - - restoreBankAccountBalances (config) { - const entities = config.keys.map((key) => { - return { - key: key, - data: { - balance: config.balance - } - }; - }); - - return this.datastore.save(entities); - } - - testTransactionalUpdate (t) { - const fromKey = this.fromKey; - const toKey = this.toKey; - const originalBalance = this.originalBalance; - const amountToTransfer = this.amountToTransfer; - const datastoreMock = datastore; - - // Overwrite so the real Datastore instance is used in `transferFunds`. - datastore = this.datastore; - - return this.restoreBankAccountBalances({ - keys: [fromKey, toKey], - balance: originalBalance - }) - .then(() => transferFunds(fromKey, toKey, amountToTransfer)) - .then(() => Promise.all([this.datastore.get(fromKey), this.datastore.get(toKey)])) - .then((results) => { - const accounts = results.map((result) => result[0]); - // Restore `datastore` to the mock API. - datastore = datastoreMock; - t.is(accounts[0].balance, originalBalance - amountToTransfer); - t.is(accounts[1].balance, originalBalance + amountToTransfer); - }) - .catch((err) => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - return Promise.reject(err); - }); - } - - testTransactionalRetry (t) { - t.plan(0); - // Overwrite so the real Datastore instance is used in `transferFunds`. - const datastoreMock = datastore; - datastore = this.datastore; - - const fromKey = this.fromKey; - const toKey = this.toKey; - - return this.restoreBankAccountBalances({ - keys: [fromKey, toKey], - balance: this.originalBalance - }) - .then(() => { - // [START transactional_retry] - function transferFundsWithRetry () { - const maxTries = 5; - let currentAttempt = 1; - let delay = 100; - - function tryRequest () { - return transferFunds(fromKey, toKey, 10) - .catch((err) => { - if (currentAttempt <= maxTries) { - // Use exponential backoff - return new Promise((resolve, reject) => { - setTimeout(() => { - currentAttempt++; - delay *= 2; - tryRequest().then(resolve, reject); - }, delay); - }); - } - return Promise.reject(err); - }); - } - - return tryRequest(1, 5); - } - // [END transactional_retry] - return transferFundsWithRetry(); - }) - .then(() => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - }) - .catch(() => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - }); - } - - testTransactionalGetOrCreate (t) { - const taskKey = this.datastore.key(['Task', Date.now()]); - - // Overwrite so the real Datastore instance is used in `transferFunds`. - const datastoreMock = datastore; - datastore = this.datastore; - - // [START transactional_get_or_create] - function getOrCreate (taskKey, taskData) { - const taskEntity = { - key: taskKey, - data: taskData - }; - - const transaction = datastore.transaction(); - - return transaction.run() - .then(() => transaction.get(taskKey)) - .then((results) => { - const task = results[0]; - if (task) { - // The task entity already exists. - return transaction.rollback(); - } else { - // Create the task entity. - transaction.save(taskEntity); - return transaction.commit(); - } - }) - .then(() => taskEntity) - .catch(() => transaction.rollback()); - } - // [END transactional_get_or_create] - - return getOrCreate(taskKey, {}) - .then((task) => { - t.truthy(task, 'Should have a task.'); - return getOrCreate(taskKey, {}); - }) - .then((task) => { - t.truthy(task, 'Should have a task.'); - // Restore `datastore` to the mock API. - datastore = datastoreMock; - }) - .catch((err) => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - return Promise.reject(err); - }); - } - - testSingleEntityGroupReadOnly (t) { - // Overwrite so the real Datastore instance is used in `transferFunds`. - const datastoreMock = datastore; - datastore = this.datastore; - - // [START transactional_single_entity_group_read_only] - function getTaskListEntities () { - let taskList, taskListEntities; - - const transaction = datastore.transaction(); - const taskListKey = datastore.key(['TaskList', 'default']); - - return transaction.run() - .then(() => datastore.get(taskListKey)) - .then((results) => { - taskList = results[0]; - const query = datastore.createQuery('Task') - .hasAncestor(taskListKey); - return datastore.runQuery(query); - }) - .then((results) => { - taskListEntities = results[0]; - return transaction.commit(); - }) - .then(() => [taskList, taskListEntities]) - .catch(() => transaction.rollback()); - } - // [END transactional_single_entity_group_read_only] - - return getTaskListEntities() - .then((results) => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - t.is(results.length, 2); - t.true(Array.isArray(results[1])); - }, (err) => { - // Restore `datastore` to the mock API. - datastore = datastoreMock; - return Promise.reject(err); - }); - } -} - -module.exports = { - Entity: Entity, - Index: Index, - Metadata: Metadata, - Query: Query, - Transaction: Transaction -}; diff --git a/datastore/error.js b/datastore/error.js deleted file mode 100644 index f0d1caab1b..0000000000 --- a/datastore/error.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const Datastore = require('@google-cloud/datastore'); - -// [START error] -function runQuery () { - // Instantiates a client - const datastore = Datastore(); - - const query = datastore.createQuery(['Company']).start('badrequest'); - - return datastore.runQuery(query) - .then((results) => { - const entities = results[0]; - console.log('Entities:'); - entities.forEach((entity) => console.log(entity)); - return entities; - }) - .catch((err) => { - console.log(err.errors); // [...] - console.log(err.code); // 400 - console.log(err.message); // "Bad Request" - console.log(err.response); // {...} - - // Process error - - // For example, treat permission error like no entities were found - if (err.code === 403) { - return []; - } - - // Forward the error to the caller - return Promise.reject(err); - }); -} -// [END error] - -exports.runQuery = runQuery; - -if (module === require.main) { - exports.runQuery(); -} diff --git a/datastore/package.json b/datastore/package.json deleted file mode 100644 index ae79053edd..0000000000 --- a/datastore/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "nodejs-docs-samples-datastore", - "version": "0.0.1", - "private": true, - "license": "Apache-2.0", - "author": "Google Inc.", - "repository": { - "type": "git", - "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" - }, - "engines": { - "node": ">=4" - }, - "scripts": { - "lint": "samples lint", - "pretest": "npm run lint", - "test": "samples test run --cmd ava -- -T 1m --verbose system-test/*.test.js" - }, - "dependencies": { - "@google-cloud/datastore": "1.1.0", - "yargs": "9.0.1" - }, - "devDependencies": { - "@google-cloud/nodejs-repo-tools": "1.4.17", - "ava": "0.22.0", - "proxyquire": "1.8.0", - "sinon": "3.3.0" - }, - "cloud-repo-tools": { - "requiresKeyFile": true, - "requiresProjectId": true, - "product": "datastore", - "samples": [ - { - "id": "tasks", - "name": "Tasks", - "file": "tasks.js", - "docs_link": "https://cloud.google.com/datastore/docs/datastore-api-tutorial", - "usage": "node tasks.js --help" - }, - { - "id": "concepts", - "name": "Concepts", - "file": "concepts.js", - "docs_link": "https://cloud.google.com/datastore/docs/concepts/entities" - }, - { - "id": "error", - "name": "Errors and Error Handling", - "file": "error.js", - "docs_link": "https://cloud.google.com/datastore/docs/concepts/errors", - "usage": { - "text": "node error.js" - } - } - ] - } -} diff --git a/datastore/quickstart.js b/datastore/quickstart.js deleted file mode 100644 index 141dd31aae..0000000000 --- a/datastore/quickstart.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -// [START datastore_quickstart] -// Imports the Google Cloud client library -const Datastore = require('@google-cloud/datastore'); - -// Your Google Cloud Platform project ID -const projectId = 'YOUR_PROJECT_ID'; - -// Instantiates a client -const datastore = Datastore({ - projectId: projectId -}); - -// The kind for the new entity -const kind = 'Task'; -// The name/ID for the new entity -const name = 'sampletask1'; -// The Cloud Datastore key for the new entity -const taskKey = datastore.key([kind, name]); - -// Prepares the new entity -const task = { - key: taskKey, - data: { - description: 'Buy milk' - } -}; - -// Saves the entity -datastore.save(task) - .then(() => { - console.log(`Saved ${task.key.name}: ${task.data.description}`); - }) - .catch((err) => { - console.error('ERROR:', err); - }); -// [END datastore_quickstart] diff --git a/datastore/system-test/concepts.test.js b/datastore/system-test/concepts.test.js deleted file mode 100644 index d2da75e4ee..0000000000 --- a/datastore/system-test/concepts.test.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const concepts = require(`../concepts`); -const test = require(`ava`); -const tools = require(`@google-cloud/nodejs-repo-tools`); - -let transaction; -let metadata; -let index; -let query; -let entity; - -const Transaction = concepts.Transaction; -const Metadata = concepts.Metadata; -const Index = concepts.Index; -const Entity = concepts.Entity; -const Query = concepts.Query; - -test.before(tools.checkCredentials); -test.before((t) => { - const projectId = process.env.GCLOUD_PROJECT; - t.truthy(projectId, `You must set the GCLOUD_PROJECT env var!`); - transaction = new Transaction(projectId); - metadata = new Metadata(projectId); - index = new Index(projectId); - entity = new Entity(projectId); - query = new Query(projectId); -}); - -test.after.always(async () => { - const datastore = transaction.datastore; - const query = datastore.createQuery(`Task`).select(`__key__`); - const [entities] = await datastore.runQuery(query); - await datastore.delete(entities.map((entity) => entity[datastore.KEY])); -}); - -test.beforeEach(tools.stubConsole); -test.afterEach.always(tools.restoreConsole); - -// Transactions -test.serial(`performs a transactional update`, (t) => transaction.testTransactionalUpdate(t)); -test.serial(`performs retries if necessary`, (t) => transaction.testTransactionalRetry(t)); -test.serial(`performs a get or create`, (t) => transaction.testTransactionalGetOrCreate(t)); -test.serial(`gets a snapshot of task list entities`, (t) => transaction.testSingleEntityGroupReadOnly(t)); - -// Metadata -test.serial(`performs a namespace query`, (t) => metadata.testNamespaceRunQuery(t)); -test.serial(`performs a kind query`, (t) => metadata.testKindRunQuery(t)); -test.serial(`performs a property query`, (t) => metadata.testPropertyRunQuery(t)); -test.serial(`performs a property by kind query`, (t) => metadata.testPropertyByKindRunQuery(t)); - -// Indexes -test.serial(`performs a query with a filter on an unindexed property`, (t) => index.testUnindexedPropertyQuery(t)); -test.serial(`inserts arrays of data`, (t) => index.testExplodingProperties(t)); - -// Queries -test.serial(`performs a basic query`, (t) => query.testRunQuery(t)); -test.serial(`performs a query with a property filter`, (t) => query.testPropertyFilter(t)); -test.serial(`performs a query with a composite filter`, (t) => query.testCompositeFilter(t)); -test.serial(`performs a query with a key filter`, (t) => query.testKeyFilter(t)); -test.serial(`performs a query with ascending sort`, (t) => query.testAscendingSort(t)); -test.serial(`performs a query with descending sort`, (t) => query.testDescendingSort(t)); -test.serial(`performs a query with multi sort`, (t) => query.testMultiSort(t)); -test.serial(`performs a kindless query`, (t) => query.testKindlessQuery(t)); -test.serial('performs a projection query', (t) => { - return entity.testProperties(t) - .then(() => { - return new Promise((resolve, reject) => { - setTimeout(() => { - query.testRunQueryProjection(t).then(resolve, reject); - }, 1000); - }); - }) - .then((results) => { - t.deepEqual(results, { - priorities: [4], - percentCompletes: [10] - }); - }); -}); -test.serial(`performs a keys only query`, (t) => query.testKeysOnlyQuery(t)); -test.serial(`performs a distinct query`, (t) => query.testDistinctQuery(t)); -test.serial(`performs a distinct on query`, (t) => query.testDistinctOnQuery(t)); -test.serial(`performs an array value inequality query`, (t) => query.testArrayValueInequalityRange(t)); -test.serial(`performs an array value equality query`, (t) => query.testArrayValueEquality(t)); -test.serial(`performs an inequality range query`, (t) => query.testInequalityRange(t)); -test.serial(`returns an error from an invalid query`, async (t) => { - await t.throws(query.testInequalityInvalid(t)); -}); -test.serial(`performs an equal and inequality range query`, (t) => query.testEqualAndInequalityRange(t)); -test.serial(`performs an equality sort query`, (t) => query.testInequalitySort(t)); -test.serial(`returns an error when not sorted on filtered property`, async (t) => { - await t.throws(query.testInequalitySortInvalidNotSame(t)); -}); -test.serial(`returns an error when not sorted on first filter prop`, async (t) => { - await t.throws(query.testInequalitySortInvalidNotFirst(t)); -}); -test.serial(`performs a query with a limit`, (t) => query.testLimit(t)); -test.serial(`allows manual pagination through results`, (t) => { - return entity.testBatchUpsert(t) - .then(() => { - return new Promise((resolve, reject) => { - setTimeout(() => { - query.testCursorPaging(t).then(resolve, reject); - }, 1000); - }); - }); -}); -test.serial(`performs an ancestor query`, (t) => query.testEventualConsistentQuery(t)); - -// Entities -test.serial(`saves with an incomplete key`, (t) => entity.testIncompleteKey(t)); -test.serial(`saves with a named key`, (t) => entity.testNamedKey(t)); -test.serial(`saves a key with a parent`, (t) => entity.testKeyWithParent(t)); -test.serial(`saves a key with multiple parents`, (t) => entity.testKeyWithMultiLevelParent(t)); -test.serial(`saves an entity with a parent`, (t) => entity.testEntityWithParent(t)); -test.serial(`saves an entity with properties`, (t) => { - t.plan(0); - return entity.testProperties(t); -}); -test.serial(`saves an entity with arrays`, (t) => entity.testArrayValue(t)); -test.serial(`saves a basic entity`, (t) => entity.testBasicEntity(t)); -test.serial(`saves with an upsert`, (t) => entity.testUpsert(t)); -test.serial(`saves with an insert`, (t) => entity.testInsert(t)); -test.serial(`performs a lookup`, (t) => entity.testLookup(t)); -test.serial(`saves with an update`, (t) => entity.testUpdate(t)); -test.serial(`deletes an entity`, (t) => entity.testDelete(t)); -test.serial(`performs a batch upsert`, (t) => { - t.plan(0); - return entity.testBatchUpsert(t); -}); -test.serial(`performs a batch lookup`, (t) => entity.testBatchLookup(t)); -test.serial(`performs a batch delete`, (t) => entity.testBatchDelete(t)); diff --git a/datastore/system-test/error.test.js b/datastore/system-test/error.test.js deleted file mode 100644 index 2816a134fe..0000000000 --- a/datastore/system-test/error.test.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const error = require('../error'); -const test = require(`ava`); -const tools = require(`@google-cloud/nodejs-repo-tools`); - -test.beforeEach(tools.stubConsole); -test.afterEach.always(tools.restoreConsole); - -test(`should have an error`, async (t) => { - const err = await t.throws(error.runQuery()); - t.truthy(err); - t.is(err.code, 400); -}); diff --git a/datastore/system-test/index.yaml b/datastore/system-test/index.yaml deleted file mode 100644 index 178a98dd50..0000000000 --- a/datastore/system-test/index.yaml +++ /dev/null @@ -1,36 +0,0 @@ -indexes: -- kind: Task - properties: - - name: done - - name: priority - direction: desc -- kind: Task - properties: - - name: priority - - name: percent_complete -- kind: Task - properties: - - name: category - - name: priority -- kind: Task - properties: - - name: priority - - name: created -- kind: Task - properties: - - name: done - - name: created -- kind: Task - properties: - - name: category - - name: priority - direction: desc -- kind: Task - properties: - - name: category - - name: created -- kind: Task - properties: - - name: priority - direction: desc - - name: created diff --git a/datastore/system-test/quickstart.test.js b/datastore/system-test/quickstart.test.js deleted file mode 100644 index 75cd8bcb11..0000000000 --- a/datastore/system-test/quickstart.test.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noPreserveCache(); -const sinon = require(`sinon`); -const test = require(`ava`); -const tools = require(`@google-cloud/nodejs-repo-tools`); - -const datastore = proxyquire(`@google-cloud/datastore`, {})(); - -const entity = { description: `Buy milk` }; -const kind = `Task`; -const name = `sampletask1`; -const key = datastore.key([kind, name]); -const datastoreEntity = Object.assign({}, entity); -datastoreEntity[datastore.KEY] = key; - -test.before(async () => { - try { - await datastore.delete(key); - } catch (err) {} // ignore error -}); -test.after.always(async () => { - try { - await datastore.delete(key); - } catch (err) {} // ignore error -}); - -test.beforeEach(tools.stubConsole); -test.afterEach.always(tools.restoreConsole); - -test.cb(`should get a task from Datastore`, (t) => { - const datastoreMock = { - key: (...args) => datastore.key(...args), - - save: (_task) => { - t.is(_task.key.kind, kind); - t.is(_task.key.name, name); - t.deepEqual(_task.data, entity); - - return datastore.save(_task) - .then(() => { - setTimeout(() => { - datastore.get(key) - .then(([task]) => { - t.deepEqual(task, datastoreEntity); - t.true(console.log.calledWith(`Saved ${name}: ${entity.description}`)); - t.end(); - }) - .catch(t.end); - }, 200); - }, t.end); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/datastore': sinon.stub().returns(datastoreMock) - }); -}); diff --git a/datastore/system-test/tasks.test.js b/datastore/system-test/tasks.test.js deleted file mode 100644 index 1126e9ccb8..0000000000 --- a/datastore/system-test/tasks.test.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const datastore = require(`@google-cloud/datastore`)(); -const path = require(`path`); -const test = require(`ava`); -const tools = require(`@google-cloud/nodejs-repo-tools`); - -const cmd = `node tasks.js`; -const cwd = path.join(__dirname, `..`); - -const description = `description`; -let key; - -test.after.always(async () => { - try { - await datastore.delete(key); - } catch (err) {} // ignore error -}); - -test.before(tools.checkCredentials); -test.beforeEach(tools.stubConsole); -test.afterEach.always(tools.restoreConsole); - -test.serial(`should add a task`, async (t) => { - t.plan(2); - const expected = /^Task (\d+) created successfully.$/; - const parts = tools.run(`${cmd} new "${description}"`, cwd).match(expected); - t.true(expected.test(parts[0])); - const [task] = await datastore.get(datastore.key([`Task`, parseInt(parts[1], 10)])); - key = task[datastore.KEY]; - t.is(task.description, description); -}); - -test.serial(`should mark a task as done`, async (t) => { - t.plan(2); - const expected = `Task ${key.id} updated successfully.`; - const output = await tools.runAsync(`${cmd} done ${key.id}`, cwd); - t.is(output, expected); - const [task] = await datastore.get(key); - t.true(task.done); -}); - -test.serial(`should list tasks`, async (t) => { - t.plan(0); - await tools.tryTest(async (assert) => { - const output = await tools.runAsync(`${cmd} list`, cwd); - assert(output.includes(key.id)); - }).start(); -}); - -test.serial(`should delete a task`, async (t) => { - t.plan(2); - const expected = `Task ${key.id} deleted successfully.`; - const output = await tools.runAsync(`${cmd} delete ${key.id}`, cwd); - t.is(output, expected); - const [task] = await datastore.get(key); - t.is(task, undefined); -}); diff --git a/datastore/tasks.js b/datastore/tasks.js deleted file mode 100644 index 6ab7c36d8a..0000000000 --- a/datastore/tasks.js +++ /dev/null @@ -1,198 +0,0 @@ -/** - * Copyright 2017, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -// [START build_service] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/google-cloud-node/#/docs/datastore/latest/guides/authentication -const Datastore = require('@google-cloud/datastore'); - -// Instantiates a client -const datastore = Datastore(); -// [END build_service] - -/* -Installation and setup instructions. -1. Download the TaskList sample application from [here] -(https://github.com/GoogleCloudPlatform/nodejs-docs-samples/archive/master.zip). - -2. Unzip the download: -```sh -unzip nodejs-docs-samples-master.zip -``` - -3. Change directories to the TaskList application: -```sh -cd nodejs-docs-samples-master/datastore -``` - -4. Install the dependencies and link the application: -```sh -npm install -``` - -5. With the gcloud SDK, be sure you are authenticated: -```sh -gcloud beta auth application-default login -``` - -6. At a command prompt, run the following, where `` is the ID of -your Google Cloud Platform project. -```sh -export GCLOUD_PROJECT= -``` - -7. Run the application! -```sh -node tasks -``` -*/ - -// [START add_entity] -function addTask (description) { - const taskKey = datastore.key('Task'); - const entity = { - key: taskKey, - data: [ - { - name: 'created', - value: new Date().toJSON() - }, - { - name: 'description', - value: description, - excludeFromIndexes: true - }, - { - name: 'done', - value: false - } - ] - }; - - datastore.save(entity) - .then(() => { - console.log(`Task ${taskKey.id} created successfully.`); - }) - .catch((err) => { - console.error('ERROR:', err); - }); -} -// [END add_entity] - -// [START update_entity] -function markDone (taskId) { - const transaction = datastore.transaction(); - const taskKey = datastore.key([ - 'Task', - taskId - ]); - - transaction.run() - .then(() => transaction.get(taskKey)) - .then((results) => { - const task = results[0]; - task.done = true; - transaction.save({ - key: taskKey, - data: task - }); - return transaction.commit(); - }) - .then(() => { - // The transaction completed successfully. - console.log(`Task ${taskId} updated successfully.`); - }) - .catch(() => transaction.rollback()); -} -// [END update_entity] - -// [START retrieve_entities] -function listTasks () { - const query = datastore.createQuery('Task') - .order('created'); - - datastore.runQuery(query) - .then((results) => { - const tasks = results[0]; - - console.log('Tasks:'); - tasks.forEach((task) => { - const taskKey = task[datastore.KEY]; - console.log(taskKey.id, task); - }); - }) - .catch((err) => { - console.error('ERROR:', err); - }); -} -// [END retrieve_entities] - -// [START delete_entity] -function deleteTask (taskId) { - const taskKey = datastore.key([ - 'Task', - taskId - ]); - - datastore.delete(taskKey) - .then(() => { - console.log(`Task ${taskId} deleted successfully.`); - }) - .catch((err) => { - console.error('ERROR:', err); - }); -} -// [END delete_entity] - -require(`yargs`) // eslint-disable-line - .demand(1) - .command( - `new `, - `Adds a task with a description .`, - {}, - (opts) => addTask(opts.description) - ) - .command( - `done `, - `Marks the specified task as done.`, - {}, - (opts) => markDone(opts.taskId) - ) - .command( - `list`, - `Lists all tasks ordered by creation time.`, - {}, - listTasks - ) - .command( - `delete `, - `Deletes a task.`, - {}, - (opts) => deleteTask(opts.taskId) - ) - .example(`node $0 new "Buy milk"`, `Adds a task with description "Buy milk".`) - .example(`node $0 done 12345`, `Marks task 12345 as Done.`) - .example(`node $0 list`, `Lists all tasks ordered by creation time`) - .example(`node $0 delete 12345`, `Deletes task 12345.`) - .wrap(120) - .recommendCommands() - .epilogue(`For more information, see https://cloud.google.com/datastore/docs`) - .help() - .strict() - .argv;