datastore/api/TaskList/Program.cs (150 lines of code) (raw):
// 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.
using Google.Cloud.Datastore.V1;
using System;
using System.Linq;
using System.Collections.Generic;
namespace GoogleCloudSamples
{
/**
* A simple Task List application demonstrating how to connect to Cloud
* Datastore, create, modify, delete, and query entities.
*/
class TaskList
{
private readonly DatastoreDb _db;
private readonly KeyFactory _keyFactory;
TaskList(string projectId)
{
// [START datastore_build_service]
// Create an authorized Datastore service using Application Default Credentials.
_db = DatastoreDb.Create(projectId);
// Create a Key factory to construct keys associated with this project.
_keyFactory = _db.CreateKeyFactory("Task");
// [END datastore_build_service]
}
// [START datastore_add_entity]
/// <summary>
/// Adds a task entity to the Datastore
/// </summary>
/// <param name="description">The task description.</param>
/// <returns>The key of the entity.</returns>
Key AddTask(string description)
{
Entity task = new Entity()
{
Key = _keyFactory.CreateIncompleteKey(),
["description"] = new Value()
{
StringValue = description,
ExcludeFromIndexes = true
},
["created"] = DateTime.UtcNow,
["done"] = false
};
return _db.Insert(task);
}
// [END datastore_add_entity]
// [START datastore_update_entity]
/// <summary>
/// Marks a task entity as done.
/// </summary>
/// <param name="id">The ID of the task entity as given by Key.</param>
/// <returns>true if the task was found.</returns>
bool MarkDone(long id)
{
using (var transaction = _db.BeginTransaction())
{
Entity task = transaction.Lookup(_keyFactory.CreateKey(id));
if (task != null)
{
task["done"] = true;
transaction.Update(task);
}
transaction.Commit();
return task != null;
}
}
// [END datastore_update_entity]
// [START datastore_retrieve_entities]
/// <summary>
/// Returns a list of all task entities in ascending order of creation time.
/// </summary>
IEnumerable<Entity> ListTasks()
{
Query query = new Query("Task")
{
Order = { { "created", PropertyOrder.Types.Direction.Descending } }
};
return _db.RunQuery(query).Entities;
}
// [END datastore_retrieve_entities]
// [START datastore_delete_entity]
/// <summary>
/// Deletes a task entity.
/// </summary>
/// <param name="id">The ID of the task entity as given by Key.</param>
void DeleteTask(long id)
{
_db.Delete(_keyFactory.CreateKey(id));
}
// [END datastore_delete_entity]
static IEnumerable<string> FormatTasks(IEnumerable<Entity> tasks)
{
var results = new List<string>();
foreach (Entity task in tasks)
{
var note = (bool)task["done"] ? "done" :
$"created {(DateTime)task["created"]}";
results.Add($"{task.Key.Path.First().Id} : " +
$"{(string)task["description"]} ({note})");
}
return results;
}
void HandleCommandLine(string commandLine)
{
string[] args = commandLine.Split(null, 2);
if (args.Length < 1)
throw new ArgumentException("not enough args");
string command = args[0];
switch (command)
{
case "new":
if (args.Length != 2)
throw new ArgumentException("missing description");
AddTask(args[1]);
Console.WriteLine("task added");
break;
case "done":
if (args.Length != 2)
throw new ArgumentException("missing task id");
long id = long.Parse(args[1]);
if (MarkDone(id))
Console.WriteLine("task marked done");
else
Console.WriteLine($"did not find a Task entity with ID {id}");
break;
case "list":
var tasks = FormatTasks(ListTasks());
Console.WriteLine($"found {tasks.Count()} tasks");
Console.WriteLine("task ID : description");
Console.WriteLine("---------------------");
foreach (string task in tasks)
Console.WriteLine(task);
break;
case "delete":
if (args.Length != 2)
throw new ArgumentException("missing task id");
DeleteTask(long.Parse(args[1]));
Console.WriteLine("task deleted (if it existed)");
break;
default:
throw new ArgumentException($"unrecognized command: {command}");
}
}
static void Main(string[] args)
{
string projectId = args.Length == 1 ? args[0] :
Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID");
Console.WriteLine($"Using project {projectId}");
if (string.IsNullOrWhiteSpace(projectId))
{
Console.WriteLine("Set the environment variable " +
"GOOGLE_PROJECT_ID or pass the google project id on" +
"the command line.");
return;
}
TaskList taskList = new TaskList(projectId);
Console.WriteLine("Cloud Datastore Task List\n");
PrintUsage();
while (true)
{
Console.Write("> ");
string commandLine = Console.ReadLine();
if (string.IsNullOrWhiteSpace(commandLine))
break;
try
{
taskList.HandleCommandLine(commandLine);
}
catch (ArgumentException e)
{
Console.WriteLine(e.Message);
PrintUsage();
}
}
Console.WriteLine("exiting");
}
private static void PrintUsage()
{
Console.WriteLine(@"Usage:
new <description> Adds a task with a description <description>
done <task-id> Marks a task as done
list Lists all tasks by creation time
delete <task-id> Deletes a task");
}
}
}