diff --git a/datastore/package.json b/datastore/package.json index ab1e49e884..852e0be414 100644 --- a/datastore/package.json +++ b/datastore/package.json @@ -4,6 +4,9 @@ "version": "0.0.1", "private": true, "license": "Apache Version 2.0", + "scripts": { + "tasks": "node tasks.js" + }, "dependencies": { "async": "^1.5.0", "gcloud": "stephenplusplus/gcloud-node#spp--datastore-v1beta3" diff --git a/datastore/tasks.js b/datastore/tasks.js new file mode 100755 index 0000000000..9e0436fc44 --- /dev/null +++ b/datastore/tasks.js @@ -0,0 +1,234 @@ +// Copyright 2015, 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'; + +var gcloud = require('gcloud'); +var input = process.argv.splice(2); +var command = input.shift(); + +var projectId = process.env.DATASTORE_PROJECT_ID || process.env.TEST_PROJECT_ID; +if (!projectId) { + throw new Error('TEST_PROJECT_ID environment variable required.'); +} + +var datastore = gcloud.datastore({ + projectId: projectId +}); + +/* +// [START build_service] +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 auth login +``` + +6. At a command prompt, run the following, where `` is the ID of +your Google Cloud Platform project. +```sh +export DATASTORE_PROJECT_ID= +``` + +7. Run the application! +```sh +npm run tasks +``` +// [END build_service] +*/ + +// [START add_entity] +function addTask(description, callback) { + var taskKey = datastore.key('Task'); + + datastore.save({ + key: taskKey, + data: { + created: new Date().toJSON(), + description: description, + done: false + } + }, function(err) { + if (err) { + callback(err); + return; + } + + callback(null, taskKey); + }); +} +// [END add_entity] + +// [START update_entity] +function markDone(taskId, callback) { + var error; + + datastore.runInTransaction(function(transaction, done) { + var taskKey = datastore.key([ + 'Task', + taskId + ]); + + transaction.get(taskKey, function(err, task) { + if (err) { + // An error occurred while getting the values. + error = err; + transaction.rollback(done); + return; + } + + task.data.done = false; + + transaction.save(task); + + done(); + }); + }, function(transactionError) { + if (transactionError || error) { + callback(transactionError || error); + } else { + // The transaction completed successfully. + callback(); + } + }); +} +// [END update_entity] + +// [START retrieve_entities] +function listTasks(callback) { + var query = datastore.createQuery('Task') + .order('created'); + + datastore.runQuery(query, callback); +} +// [END retrieve_entities] + +// [START delete_task] +function deleteTask(taskId, callback) { + var taskKey = datastore.key([ + 'Task', + taskId + ]); + + datastore.delete(taskKey, callback); +} +// [END delete_task] + +// [START format_results] +function formatTasks(tasks) { + return tasks + .map(function(task) { + var taskKey = task.key.path.pop(); + var status; + + if (task.data.done) { + status = 'done'; + } else { + status = 'created ' + new Date(task.data.created); + } + + return taskKey + ' : ' + task.data.description + ' (' + status + ')'; + }) + .join('\n'); +} +// [END format_results] + +switch (command) { + case 'new': { + addTask(input, function(err, taskKey) { + if (err) { + throw err; + } + + var taskId = taskKey.path.pop(); + + console.log('Task %d created successfully.', taskId); + }); + + break; + } + + case 'done': { + var taskId = parseInt(input, 10); + + markDone(taskId, function(err) { + if (err) { + throw err; + } + + console.log('Task %d updated successfully.', taskId); + }); + + break; + } + + case 'list': { + listTasks(function(err, tasks) { + if (err) { + throw err; + } + + console.log(formatTasks(tasks)); + }); + + break; + } + + case 'delete': { + var taskId = parseInt(input, 10); + + deleteTask(taskId, function(err) { + if (err) { + throw err; + } + + console.log('Task %d deleted successfully.', taskId); + }); + + break; + } + + default: { + console.log([ + 'Usage:', + '', + ' new Adds a task with a description ', + ' done Marks a task as done', + ' list Lists all tasks by creation time', + ' delete Deletes a task' + ].join('\n')); + } +} + +module.exports.addEntity = addTask; +module.exports.updateEntity = markDone; +module.exports.retrieveEntities = listTasks; +module.exports.deleteEntity = deleteTask; +module.exports.formatResults = formatTasks; diff --git a/test/datastore/tasks.test.js b/test/datastore/tasks.test.js new file mode 100644 index 0000000000..d011a8e2cb --- /dev/null +++ b/test/datastore/tasks.test.js @@ -0,0 +1,104 @@ +// Copyright 2015, 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'; + +var assert = require('assert'); + +var tasks = require('../../datastore/tasks.js'); + +describe('adding an entity', function() { + it('should add a task', function(done) { + tasks.addEntity('description', done); + }); +}); + +describe('updating an entity', function() { + var taskId; + + before(function(done) { + getTaskId(function(err, _taskId) { + if (err) { + done(err); + return; + } + + taskId = _taskId; + done(); + }); + }); + + it('should mark a task as done', function(done) { + tasks.updateEntity(taskId, done); + }); +}); + +describe('retrieving entities', function() { + it('should list tasks', function(done) { + tasks.retrieveEntities(done); + }); +}); + +describe('deleting an entity', function() { + var taskId; + + before(function(done) { + getTaskId(function(err, _taskId) { + if (err) { + done(err); + return; + } + + taskId = _taskId; + done(); + }); + }); + + it('should delete a task', function(done) { + tasks.deleteEntity(taskId, done); + }); +}); + +describe('formatting results', function() { + var tasks; + + before(function(done) { + tasks.retrieveEntities(function(err, _tasks) { + if (err) { + done(err); + return; + } + + tasks = _tasks; + done(); + }); + }); + + it('should format tasks', function() { + assert.doesNotThrow(function() { + tasks.formatResults(tasks); + }); + }); +}); + +function getTaskId(callback) { + tasks.addEntity('description', function(err, taskKey) { + if (err) { + callback(err); + return; + } + + var taskId = taskKey.path.pop(); + callback(null, taskId); + }); +}