|
|
@@ -26,6 +26,7 @@ struct Thing : Codable {
|
|
|
var number: Int
|
|
|
}
|
|
|
|
|
|
+// Convert Encodable objects to dictionaries of property-value pairs.
|
|
|
class PropertiesEncoder {
|
|
|
static func encode<T : Encodable>(_ value : T) throws -> [String:Any]? {
|
|
|
let plist = try PropertyListEncoder().encode(value)
|
|
|
@@ -34,6 +35,7 @@ class PropertiesEncoder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// Create Decodable objects from dictionaries of property-value pairs.
|
|
|
class PropertiesDecoder {
|
|
|
static func decode<T: Decodable>(_ type: T.Type, from: [String:Any]) throws -> T {
|
|
|
let plist = try PropertyListSerialization.data(fromPropertyList: from,
|
|
|
@@ -42,14 +44,42 @@ class PropertiesDecoder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func runSelectQuery(service: Google_Datastore_V1_DatastoreService) throws {
|
|
|
+func prepareService() throws -> Google_Datastore_V1_DatastoreService? {
|
|
|
+ // Get an OAuth token
|
|
|
+ var authToken : String!
|
|
|
+ if let provider = DefaultTokenProvider(scopes:scopes) {
|
|
|
+ let sem = DispatchSemaphore(value: 0)
|
|
|
+ try provider.withToken() {(token, error) -> Void in
|
|
|
+ if let token = token {
|
|
|
+ authToken = token.AccessToken
|
|
|
+ }
|
|
|
+ sem.signal()
|
|
|
+ }
|
|
|
+ sem.wait()
|
|
|
+ }
|
|
|
+ if authToken == nil {
|
|
|
+ print("ERROR: No OAuth token is available. Did you set GOOGLE_APPLICATION_CREDENTIALS?")
|
|
|
+ exit(-1)
|
|
|
+ }
|
|
|
+ // Initialize gRPC service
|
|
|
+ gRPC.initialize()
|
|
|
+ let certificateURL = URL(fileURLWithPath:"/roots.pem")
|
|
|
+ let certificates = try! String(contentsOf: certificateURL, encoding: .utf8)
|
|
|
+ let service = Google_Datastore_V1_DatastoreService(address:"datastore.googleapis.com",
|
|
|
+ certificates:certificates,
|
|
|
+ host:nil)
|
|
|
+ service.metadata = Metadata(["authorization":"Bearer " + authToken])
|
|
|
+ return service
|
|
|
+}
|
|
|
+
|
|
|
+func performList(service: Google_Datastore_V1_DatastoreService) throws {
|
|
|
var request = Google_Datastore_V1_RunQueryRequest()
|
|
|
request.projectID = projectID
|
|
|
var query = Google_Datastore_V1_GqlQuery()
|
|
|
query.queryString = "select * from Thing"
|
|
|
request.gqlQuery = query
|
|
|
let result = try service.runquery(request)
|
|
|
- var entities : [Thing] = []
|
|
|
+ var entities : [Int64 : Thing] = [:]
|
|
|
for entityResult in result.batch.entityResults {
|
|
|
var properties : [String:Any] = [:]
|
|
|
for property in entityResult.entity.properties {
|
|
|
@@ -64,12 +94,12 @@ func runSelectQuery(service: Google_Datastore_V1_DatastoreService) throws {
|
|
|
}
|
|
|
}
|
|
|
let entity = try PropertiesDecoder.decode(Thing.self, from:properties)
|
|
|
- entities.append(entity)
|
|
|
+ entities[entityResult.entity.key.path[0].id] = entity
|
|
|
}
|
|
|
print("\(entities)")
|
|
|
}
|
|
|
|
|
|
-func runInsert(service: Google_Datastore_V1_DatastoreService,
|
|
|
+func performInsert(service: Google_Datastore_V1_DatastoreService,
|
|
|
number: Int) throws {
|
|
|
var request = Google_Datastore_V1_CommitRequest()
|
|
|
request.projectID = projectID
|
|
|
@@ -94,19 +124,16 @@ func runInsert(service: Google_Datastore_V1_DatastoreService,
|
|
|
}
|
|
|
entity.properties[k] = value
|
|
|
}
|
|
|
-
|
|
|
var mutation = Google_Datastore_V1_Mutation()
|
|
|
mutation.insert = entity
|
|
|
request.mutations.append(mutation)
|
|
|
-
|
|
|
let result = try service.commit(request)
|
|
|
-
|
|
|
for mutationResult in result.mutationResults {
|
|
|
print("\(mutationResult)")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func runDelete(service: Google_Datastore_V1_DatastoreService,
|
|
|
+func performDelete(service: Google_Datastore_V1_DatastoreService,
|
|
|
kind: String,
|
|
|
id: Int64) throws {
|
|
|
var request = Google_Datastore_V1_CommitRequest()
|
|
|
@@ -126,50 +153,22 @@ func runDelete(service: Google_Datastore_V1_DatastoreService,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func prepareService() throws -> Google_Datastore_V1_DatastoreService? {
|
|
|
- // Get an OAuth token
|
|
|
- var authToken : String!
|
|
|
- if let provider = DefaultTokenProvider(scopes:scopes) {
|
|
|
- let sem = DispatchSemaphore(value: 0)
|
|
|
- try provider.withToken() {(token, error) -> Void in
|
|
|
- if let token = token {
|
|
|
- authToken = token.AccessToken
|
|
|
- }
|
|
|
- sem.signal()
|
|
|
- }
|
|
|
- sem.wait()
|
|
|
- }
|
|
|
- if authToken == nil {
|
|
|
- print("ERROR: No OAuth token is available. Did you set GOOGLE_APPLICATION_CREDENTIALS?")
|
|
|
- exit(-1)
|
|
|
- }
|
|
|
- // Initialize gRPC service
|
|
|
- gRPC.initialize()
|
|
|
- let certificateURL = URL(fileURLWithPath:"/roots.pem")
|
|
|
- let certificates = try! String(contentsOf: certificateURL, encoding: .utf8)
|
|
|
- let service = Google_Datastore_V1_DatastoreService(address:"datastore.googleapis.com",
|
|
|
- certificates:certificates,
|
|
|
- host:nil)
|
|
|
- service.metadata = Metadata(["authorization":"Bearer " + authToken])
|
|
|
- return service
|
|
|
-}
|
|
|
-
|
|
|
Group {
|
|
|
$0.command("insert") { (number:Int) in
|
|
|
if let service = try prepareService() {
|
|
|
- try runInsert(service:service, number:number)
|
|
|
+ try performInsert(service:service, number:number)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$0.command("delete") { (id:Int) in
|
|
|
if let service = try prepareService() {
|
|
|
- try runDelete(service:service, kind:"Thing", id:Int64(id))
|
|
|
+ try performDelete(service:service, kind:"Thing", id:Int64(id))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $0.command("query") {
|
|
|
+ $0.command("list") {
|
|
|
if let service = try prepareService() {
|
|
|
- try runSelectQuery(service:service)
|
|
|
+ try performList(service:service)
|
|
|
}
|
|
|
}
|
|
|
|