Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(746)

Side by Side Diff: lib/src/datastore_impl.dart

Issue 2285803002: Upgrade to use stable `package:googleapis/v1.dart` of datastore (Closed) Base URL: git@github.com:dart-lang/gcloud.git@master
Patch Set: Update upper constraint on http_parser Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/db.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library gcloud.datastore_impl; 5 library gcloud.datastore_impl;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:http/http.dart' as http; 9 import 'package:http/http.dart' as http;
10 10
11 import '../datastore.dart' as datastore; 11 import '../datastore.dart' as datastore;
12 import '../common.dart' show Page; 12 import '../common.dart' show Page;
13 import 'package:googleapis_beta/datastore/v1beta2.dart' as api; 13 import 'package:googleapis/datastore/v1.dart' as api;
14 14
15 class TransactionImpl implements datastore.Transaction { 15 class TransactionImpl implements datastore.Transaction {
16 final String data; 16 final String data;
17 TransactionImpl(this.data); 17 TransactionImpl(this.data);
18 } 18 }
19 19
20 class DatastoreImpl implements datastore.Datastore { 20 class DatastoreImpl implements datastore.Datastore {
21 static const List<String> SCOPES = const <String>[ 21 static const List<String> SCOPES = const <String>[
22 api.DatastoreApi.DatastoreScope, 22 api.DatastoreApi.DatastoreScope,
23 api.DatastoreApi.UserinfoEmailScope, 23 api.DatastoreApi.CloudPlatformScope,
24 ]; 24 ];
25 25
26 final api.DatastoreApi _api; 26 final api.DatastoreApi _api;
27 final String _project; 27 final String _project;
28 28
29 DatastoreImpl(http.Client client, this._project) 29 /// The [project] parameter is the name of the cloud project (it should not
30 : _api = new api.DatastoreApi(client); 30 /// start with a `s~`).
31 DatastoreImpl(http.Client client, String project)
32 : _api = new api.DatastoreApi(client), _project = project;
31 33
32 api.Key _convertDatastore2ApiKey(datastore.Key key, {bool enforceId: true}) { 34 api.Key _convertDatastore2ApiKey(datastore.Key key, {bool enforceId: true}) {
33 var apiKey = new api.Key(); 35 var apiKey = new api.Key();
34 36
35 apiKey.partitionId = new api.PartitionId() 37 apiKey.partitionId = new api.PartitionId()
36 ..datasetId = _project 38 ..projectId = _project
37 ..namespace = key.partition.namespace; 39 ..namespaceId = key.partition.namespace;
38 40
39 apiKey.path = key.elements.map((datastore.KeyElement element) { 41 apiKey.path = key.elements.map((datastore.KeyElement element) {
40 var part = new api.KeyPathElement(); 42 var part = new api.PathElement();
41 part.kind = element.kind; 43 part.kind = element.kind;
42 if (element.id is int) { 44 if (element.id is int) {
43 part.id = '${element.id}'; 45 part.id = '${element.id}';
44 } else if (element.id is String) { 46 } else if (element.id is String) {
45 part.name = element.id; 47 part.name = element.id;
46 } else if (enforceId) { 48 } else if (enforceId) {
47 throw new datastore.ApplicationError( 49 throw new datastore.ApplicationError(
48 'Error while encoding entity key: Using `null` as the id is not ' 50 'Error while encoding entity key: Using `null` as the id is not '
49 'allowed.'); 51 'allowed.');
50 } 52 }
51 return part; 53 return part;
52 }).toList(); 54 }).toList();
53 55
54 return apiKey; 56 return apiKey;
55 } 57 }
56 58
57 static datastore.Key _convertApi2DatastoreKey(api.Key key) { 59 static datastore.Key _convertApi2DatastoreKey(api.Key key) {
58 var elements = key.path.map((api.KeyPathElement element) { 60 var elements = key.path.map((api.PathElement element) {
59 if (element.id != null) { 61 if (element.id != null) {
60 return new datastore.KeyElement(element.kind, int.parse(element.id)); 62 return new datastore.KeyElement(element.kind, int.parse(element.id));
61 } else if (element.name != null) { 63 } else if (element.name != null) {
62 return new datastore.KeyElement(element.kind, element.name); 64 return new datastore.KeyElement(element.kind, element.name);
63 } else { 65 } else {
64 throw new datastore.DatastoreError( 66 throw new datastore.DatastoreError(
65 'Invalid server response: Expected allocated name/id.'); 67 'Invalid server response: Expected allocated name/id.');
66 } 68 }
67 }).toList(); 69 }).toList();
68 70
69 var partition; 71 var partition;
70 if (key.partitionId != null) { 72 if (key.partitionId != null) {
71 partition = new datastore.Partition(key.partitionId.namespace); 73 partition = new datastore.Partition(key.partitionId.namespaceId);
72 // TODO: assert projectId. 74 // TODO: assert projectId.
73 } 75 }
74 return new datastore.Key(elements, partition: partition); 76 return new datastore.Key(elements, partition: partition);
75 } 77 }
76 78
77 bool _compareApiKey(api.Key a, api.Key b) { 79 bool _compareApiKey(api.Key a, api.Key b) {
78 if (a.path.length != b.path.length) return false; 80 if (a.path.length != b.path.length) return false;
79 81
80 // FIXME(Issue #2): Is this comparison working correctly? 82 // FIXME(Issue #2): Is this comparison working correctly?
81 if (a.partitionId != null) { 83 if (a.partitionId != null) {
82 if (b.partitionId == null) return false; 84 if (b.partitionId == null) return false;
83 if (a.partitionId.datasetId != b.partitionId.datasetId) return false; 85 if (a.partitionId.projectId != b.partitionId.projectId) return false;
84 if (a.partitionId.namespace != b.partitionId.namespace) return false; 86 if (a.partitionId.namespaceId != b.partitionId.namespaceId) return false;
85 } else { 87 } else {
86 if (b.partitionId != null) return false; 88 if (b.partitionId != null) return false;
87 } 89 }
88 90
89 for (int i = 0; i < a.path.length; i++) { 91 for (int i = 0; i < a.path.length; i++) {
90 if (a.path[i].id != b.path[i].id || 92 if (a.path[i].id != b.path[i].id ||
91 a.path[i].name != b.path[i].name || 93 a.path[i].name != b.path[i].name ||
92 a.path[i].kind != b.path[i].kind) return false; 94 a.path[i].kind != b.path[i].kind) return false;
93 } 95 }
94 return true; 96 return true;
95 } 97 }
96 98
97 static _convertApi2DatastorePropertyValue(api.Value value) {
98 if (value.booleanValue != null)
99 return value.booleanValue;
100 else if (value.integerValue != null)
101 return int.parse(value.integerValue);
102 else if (value.doubleValue != null)
103 return value.doubleValue;
104 else if (value.stringValue != null)
105 return value.stringValue;
106 else if (value.dateTimeValue != null)
107 return value.dateTimeValue;
108 else if (value.blobValue != null)
109 return new datastore.BlobValue(value.blobValueAsBytes);
110 else if (value.keyValue != null)
111 return _convertApi2DatastoreKey(value.keyValue);
112 else if (value.listValue != null)
113 // FIXME(Issue #3): Consistently handle exceptions.
114 throw new Exception('Cannot have lists inside lists.');
115 else if (value.blobKeyValue != null)
116 throw new UnsupportedError('Blob keys are not supported.');
117 else if (value.entityValue != null)
118 throw new UnsupportedError('Entity values are not supported.');
119 return null;
120 }
121
122 api.Value _convertDatastore2ApiPropertyValue( 99 api.Value _convertDatastore2ApiPropertyValue(
123 value, bool indexed, {bool lists: true}) { 100 value, bool indexed, {bool lists: true}) {
124 var apiValue = new api.Value() 101 var apiValue = new api.Value()
125 ..indexed = indexed; 102 ..excludeFromIndexes = !indexed;
126 if (value == null) { 103 if (value == null) {
127 return apiValue; 104 return apiValue
105 ..nullValue = "NULL_VALUE";
128 } else if (value is bool) { 106 } else if (value is bool) {
129 return apiValue 107 return apiValue
130 ..booleanValue = value; 108 ..booleanValue = value;
131 } else if (value is int) { 109 } else if (value is int) {
132 return apiValue 110 return apiValue
133 ..integerValue = '$value'; 111 ..integerValue = '$value';
134 } else if (value is double) { 112 } else if (value is double) {
135 return apiValue 113 return apiValue
136 ..doubleValue = value; 114 ..doubleValue = value;
137 } else if (value is String) { 115 } else if (value is String) {
138 return apiValue 116 return apiValue
139 ..stringValue = value; 117 ..stringValue = value;
140 } else if (value is DateTime) { 118 } else if (value is DateTime) {
141 return apiValue 119 return apiValue
142 ..dateTimeValue = value; 120 ..timestampValue = value.toIso8601String();
143 } else if (value is datastore.BlobValue) { 121 } else if (value is datastore.BlobValue) {
144 return apiValue 122 return apiValue
145 ..blobValueAsBytes = value.bytes; 123 ..blobValueAsBytes = value.bytes;
146 } else if (value is datastore.Key) { 124 } else if (value is datastore.Key) {
147 return apiValue 125 return apiValue
148 ..keyValue = _convertDatastore2ApiKey(value, enforceId: false); 126 ..keyValue = _convertDatastore2ApiKey(value, enforceId: false);
149 } else if (value is List) { 127 } else if (value is List) {
150 if (!lists) { 128 if (!lists) {
151 // FIXME(Issue #3): Consistently handle exceptions. 129 // FIXME(Issue #3): Consistently handle exceptions.
152 throw new Exception('List values are not allowed.'); 130 throw new Exception('List values are not allowed.');
153 } 131 }
154 132
155 convertItem(i) 133 convertItem(i)
156 => _convertDatastore2ApiPropertyValue(i, indexed, lists: false); 134 => _convertDatastore2ApiPropertyValue(i, indexed, lists: false);
157 135
158 return new api.Value() 136 return new api.Value()..arrayValue = (
159 ..listValue = value.map(convertItem).toList(); 137 new api.ArrayValue()..values = value.map(convertItem).toList());
160 } else { 138 } else {
161 throw new UnsupportedError( 139 throw new UnsupportedError(
162 'Types ${value.runtimeType} cannot be used for serializing.'); 140 'Types ${value.runtimeType} cannot be used for serializing.');
163 } 141 }
164 } 142 }
165 143
166 static _convertApi2DatastoreProperty(api.Property property) { 144 static dynamic _convertApi2DatastoreProperty(api.Value value) {
167 if (property.booleanValue != null) 145 if (value.booleanValue != null)
168 return property.booleanValue; 146 return value.booleanValue;
169 else if (property.integerValue != null) 147 else if (value.integerValue != null)
170 return int.parse(property.integerValue); 148 return int.parse(value.integerValue);
171 else if (property.doubleValue != null) 149 else if (value.doubleValue != null)
172 return property.doubleValue; 150 return value.doubleValue;
173 else if (property.stringValue != null) 151 else if (value.stringValue != null)
174 return property.stringValue; 152 return value.stringValue;
175 else if (property.dateTimeValue != null) 153 else if (value.timestampValue != null)
176 return property.dateTimeValue; 154 return DateTime.parse(value.timestampValue);
177 else if (property.blobValue != null) 155 else if (value.blobValue != null)
178 return new datastore.BlobValue(property.blobValueAsBytes); 156 return new datastore.BlobValue(value.blobValueAsBytes);
179 else if (property.keyValue != null) 157 else if (value.keyValue != null)
180 return _convertApi2DatastoreKey(property.keyValue); 158 return _convertApi2DatastoreKey(value.keyValue);
181 else if (property.listValue != null) 159 else if (value.arrayValue != null && value.arrayValue.values != null)
182 return 160 return value
183 property.listValue.map(_convertApi2DatastorePropertyValue).toList(); 161 .arrayValue.values.map(_convertApi2DatastoreProperty).toList();
184 else if (property.blobKeyValue != null) 162 else if (value.entityValue != null)
185 throw new UnsupportedError('Blob keys are not supported.');
186 else if (property.entityValue != null)
187 throw new UnsupportedError('Entity values are not supported.'); 163 throw new UnsupportedError('Entity values are not supported.');
164 else if (value.geoPointValue != null)
165 throw new UnsupportedError('GeoPoint values are not supported.');
188 return null; 166 return null;
189 } 167 }
190 168
191 api.Property _convertDatastore2ApiProperty(
192 value, bool indexed, {bool lists: true}) {
193 var apiProperty = new api.Property()
194 ..indexed = indexed;
195 if (value == null) {
196 return null;
197 } else if (value is bool) {
198 return apiProperty
199 ..booleanValue = value;
200 } else if (value is int) {
201 return apiProperty
202 ..integerValue = '$value';
203 } else if (value is double) {
204 return apiProperty
205 ..doubleValue = value;
206 } else if (value is String) {
207 return apiProperty
208 ..stringValue = value;
209 } else if (value is DateTime) {
210 return apiProperty
211 ..dateTimeValue = value;
212 } else if (value is datastore.BlobValue) {
213 return apiProperty
214 ..blobValueAsBytes = value.bytes;
215 } else if (value is datastore.Key) {
216 return apiProperty
217 ..keyValue = _convertDatastore2ApiKey(value, enforceId: false);
218 } else if (value is List) {
219 if (!lists) {
220 // FIXME(Issue #3): Consistently handle exceptions.
221 throw new Exception('List values are not allowed.');
222 }
223 convertItem(i)
224 => _convertDatastore2ApiPropertyValue(i, indexed, lists: false);
225 return new api.Property()..listValue = value.map(convertItem).toList();
226 } else {
227 throw new UnsupportedError(
228 'Types ${value.runtimeType} cannot be used for serializing.');
229 }
230 }
231
232 static datastore.Entity _convertApi2DatastoreEntity(api.Entity entity) { 169 static datastore.Entity _convertApi2DatastoreEntity(api.Entity entity) {
233 var unindexedProperties = new Set(); 170 var unindexedProperties = new Set();
234 var properties = {}; 171 var properties = {};
235 172
236 if (entity.properties != null) { 173 if (entity.properties != null) {
237 entity.properties.forEach((String name, api.Property property) { 174 entity.properties.forEach((String name, api.Value value) {
238 properties[name] = _convertApi2DatastoreProperty(property); 175 properties[name] = _convertApi2DatastoreProperty(value);
239 if (property.indexed == false) { 176 if (value.excludeFromIndexes != null &&
240 // TODO(Issue #$4): Should we support mixed indexed/non-indexed list 177 value.excludeFromIndexes) {
241 // values? 178 unindexedProperties.add(name);
242 if (property.listValue != null) {
243 if (property.listValue.length > 0) {
244 var firstIndexed = property.listValue.first.indexed;
245 for (int i = 1; i < property.listValue.length; i++) {
246 if (property.listValue[i].indexed != firstIndexed) {
247 throw new Exception('Some list entries are indexed and some '
248 'are not. This is currently not supported.');
249 }
250 }
251 if (firstIndexed == false) {
252 unindexedProperties.add(name);
253 }
254 }
255 } else {
256 unindexedProperties.add(name);
257 }
258 } 179 }
259 }); 180 });
260 } 181 }
261 return new datastore.Entity(_convertApi2DatastoreKey(entity.key), 182 return new datastore.Entity(_convertApi2DatastoreKey(entity.key),
262 properties, 183 properties,
263 unIndexedProperties: unindexedProperties); 184 unIndexedProperties: unindexedProperties);
264 } 185 }
265 186
266 api.Entity _convertDatastore2ApiEntity(datastore.Entity entity, 187 api.Entity _convertDatastore2ApiEntity(datastore.Entity entity,
267 {bool enforceId: false}) { 188 {bool enforceId: false}) {
(...skipping 28 matching lines...) Expand all
296 var pf = new api.PropertyFilter(); 217 var pf = new api.PropertyFilter();
297 var operator = relationMapping[filter.relation]; 218 var operator = relationMapping[filter.relation];
298 // FIXME(Issue #5): Is this OK? 219 // FIXME(Issue #5): Is this OK?
299 if (filter.relation == datastore.FilterRelation.In) { 220 if (filter.relation == datastore.FilterRelation.In) {
300 operator = 'EQUAL'; 221 operator = 'EQUAL';
301 } 222 }
302 223
303 if (operator == null) { 224 if (operator == null) {
304 throw new ArgumentError('Unknown filter relation: ${filter.relation}.'); 225 throw new ArgumentError('Unknown filter relation: ${filter.relation}.');
305 } 226 }
306 pf.operator = operator; 227 pf.op = operator;
307 pf.property = new api.PropertyReference()..name = filter.name; 228 pf.property = new api.PropertyReference()..name = filter.name;
308 229
309 // FIXME(Issue #5): Is this OK? 230 // FIXME(Issue #5): Is this OK?
310 var value = filter.value; 231 var value = filter.value;
311 if (filter.relation == datastore.FilterRelation.In) { 232 if (filter.relation == datastore.FilterRelation.In) {
312 if (value is List && value.length == 1) { 233 if (value is List && value.length == 1) {
313 value = value.first; 234 value = value.first;
314 } else { 235 } else {
315 throw new ArgumentError('List values not supported (was: $value).'); 236 throw new ArgumentError('List values not supported (was: $value).');
316 } 237 }
317 } 238 }
318 239
319 pf.value = _convertDatastore2ApiPropertyValue(value, true, lists: false); 240 pf.value = _convertDatastore2ApiPropertyValue(value, true, lists: false);
320 return new api.Filter()..propertyFilter = pf; 241 return new api.Filter()..propertyFilter = pf;
321 } 242 }
322 243
323 api.Filter _convertDatastoreAncestorKey2ApiFilter(datastore.Key key) { 244 api.Filter _convertDatastoreAncestorKey2ApiFilter(datastore.Key key) {
324 var pf = new api.PropertyFilter(); 245 var pf = new api.PropertyFilter();
325 pf.operator = 'HAS_ANCESTOR'; 246 pf.op = 'HAS_ANCESTOR';
326 pf.property = new api.PropertyReference()..name = '__key__'; 247 pf.property = new api.PropertyReference()..name = '__key__';
327 pf.value = new api.Value() 248 pf.value = new api.Value()
328 ..keyValue = _convertDatastore2ApiKey(key, enforceId: true); 249 ..keyValue = _convertDatastore2ApiKey(key, enforceId: true);
329 return new api.Filter()..propertyFilter = pf; 250 return new api.Filter()..propertyFilter = pf;
330 } 251 }
331 252
332 api.Filter _convertDatastore2ApiFilters(List<datastore.Filter> filters, 253 api.Filter _convertDatastore2ApiFilters(List<datastore.Filter> filters,
333 datastore.Key ancestorKey) { 254 datastore.Key ancestorKey) {
334 if ((filters == null || filters.length == 0) && ancestorKey == null) { 255 if ((filters == null || filters.length == 0) && ancestorKey == null) {
335 return null; 256 return null;
336 } 257 }
337 258
338 var compFilter = new api.CompositeFilter(); 259 var compFilter = new api.CompositeFilter();
339 if (filters != null) { 260 if (filters != null) {
340 compFilter.filters = filters.map(_convertDatastore2ApiFilter).toList(); 261 compFilter.filters = filters.map(_convertDatastore2ApiFilter).toList();
341 } 262 }
342 if (ancestorKey != null) { 263 if (ancestorKey != null) {
343 var filter = _convertDatastoreAncestorKey2ApiFilter(ancestorKey); 264 var filter = _convertDatastoreAncestorKey2ApiFilter(ancestorKey);
344 if (compFilter.filters == null) { 265 if (compFilter.filters == null) {
345 compFilter.filters = [filter]; 266 compFilter.filters = [filter];
346 } else { 267 } else {
347 compFilter.filters.add(filter); 268 compFilter.filters.add(filter);
348 } 269 }
349 } 270 }
350 compFilter.operator = 'AND'; 271 compFilter.op = 'AND';
351 return new api.Filter()..compositeFilter = compFilter; 272 return new api.Filter()..compositeFilter = compFilter;
352 } 273 }
353 274
354 api.PropertyOrder _convertDatastore2ApiOrder(datastore.Order order) { 275 api.PropertyOrder _convertDatastore2ApiOrder(datastore.Order order) {
355 var property = new api.PropertyReference()..name = order.propertyName; 276 var property = new api.PropertyReference()..name = order.propertyName;
356 var direction = order.direction == datastore.OrderDirection.Ascending 277 var direction = order.direction == datastore.OrderDirection.Ascending
357 ? 'ASCENDING' : 'DESCENDING'; 278 ? 'ASCENDING' : 'DESCENDING';
358 return new api.PropertyOrder() 279 return new api.PropertyOrder()
359 ..direction = direction 280 ..direction = direction
360 ..property = property; 281 ..property = property;
(...skipping 21 matching lines...) Expand all
382 } 303 }
383 } 304 }
384 return new Future.error(error, stack); 305 return new Future.error(error, stack);
385 } 306 }
386 307
387 Future<List<datastore.Key>> allocateIds(List<datastore.Key> keys) { 308 Future<List<datastore.Key>> allocateIds(List<datastore.Key> keys) {
388 var request = new api.AllocateIdsRequest(); 309 var request = new api.AllocateIdsRequest();
389 request..keys = keys.map((key) { 310 request..keys = keys.map((key) {
390 return _convertDatastore2ApiKey(key, enforceId: false); 311 return _convertDatastore2ApiKey(key, enforceId: false);
391 }).toList(); 312 }).toList();
392 return _api.datasets.allocateIds(request, _project).then((response) { 313 return _api.projects.allocateIds(request, _project).then((response) {
393 return response.keys.map(_convertApi2DatastoreKey).toList(); 314 return response.keys.map(_convertApi2DatastoreKey).toList();
394 }, onError: _handleError); 315 }, onError: _handleError);
395 } 316 }
396 317
397 Future<datastore.Transaction> beginTransaction( 318 Future<datastore.Transaction> beginTransaction(
398 {bool crossEntityGroup: false}) { 319 {bool crossEntityGroup: false}) {
399 var request = new api.BeginTransactionRequest(); 320 var request = new api.BeginTransactionRequest();
400 // TODO: Should this be made configurable? 321 return _api.projects.beginTransaction(request, _project).then((result) {
401 request.isolationLevel = 'SERIALIZABLE';
402 return _api.datasets.beginTransaction(request, _project).then((result) {
403 return new TransactionImpl(result.transaction); 322 return new TransactionImpl(result.transaction);
404 }, onError: _handleError); 323 }, onError: _handleError);
405 } 324 }
406 325
407 Future<datastore.CommitResult> commit({List<datastore.Entity> inserts, 326 Future<datastore.CommitResult> commit({List<datastore.Entity> inserts,
408 List<datastore.Entity> autoIdInserts, 327 List<datastore.Entity> autoIdInserts,
409 List<datastore.Key> deletes, 328 List<datastore.Key> deletes,
410 datastore.Transaction transaction}) { 329 datastore.Transaction transaction}) {
411 var request = new api.CommitRequest(); 330 var request = new api.CommitRequest();
412 331
413 if (transaction != null) { 332 if (transaction != null) {
414 request.mode = 'TRANSACTIONAL'; 333 request.mode = 'TRANSACTIONAL';
415 request.transaction = (transaction as TransactionImpl).data; 334 request.transaction = (transaction as TransactionImpl).data;
416 } else { 335 } else {
417 request.mode = 'NON_TRANSACTIONAL'; 336 request.mode = 'NON_TRANSACTIONAL';
418 } 337 }
419 338
420 request.mutation = new api.Mutation(); 339 var mutations = request.mutations = [];
421 if (inserts != null) { 340 if (inserts != null) {
422 request.mutation.upsert = new List(inserts.length);
423 for (int i = 0; i < inserts.length; i++) { 341 for (int i = 0; i < inserts.length; i++) {
424 request.mutation.upsert[i] = _convertDatastore2ApiEntity(inserts[i]); 342 mutations.add(
343 new api.Mutation()..upsert =
344 _convertDatastore2ApiEntity(inserts[i], enforceId: true));
425 } 345 }
426 } 346 }
347 int autoIdStartIndex = -1;
427 if (autoIdInserts != null) { 348 if (autoIdInserts != null) {
428 request.mutation.insertAutoId = new List(autoIdInserts.length); 349 autoIdStartIndex = mutations.length;
429 for (int i = 0; i < autoIdInserts.length; i++) { 350 for (int i = 0; i < autoIdInserts.length; i++) {
430 request.mutation.insertAutoId[i] = 351 mutations.add(
431 _convertDatastore2ApiEntity(autoIdInserts[i], enforceId: false); 352 new api.Mutation()..insert =
353 _convertDatastore2ApiEntity(autoIdInserts[i], enforceId: false));
432 } 354 }
433 } 355 }
434 if (deletes != null) { 356 if (deletes != null) {
435 request.mutation.delete = new List(deletes.length);
436 for (int i = 0; i < deletes.length; i++) { 357 for (int i = 0; i < deletes.length; i++) {
437 request.mutation.delete[i] = 358 mutations.add(
438 _convertDatastore2ApiKey(deletes[i], enforceId: true); 359 new api.Mutation()..delete =
360 _convertDatastore2ApiKey(deletes[i], enforceId: true));
439 } 361 }
440 } 362 }
441 return _api.datasets.commit(request, _project).then((result) { 363 return _api.projects.commit(request, _project).then((result) {
442 var keys; 364 var keys;
443 if (autoIdInserts != null && autoIdInserts.length > 0) { 365 if (autoIdInserts != null && autoIdInserts.length > 0) {
444 keys = result 366 List<api.MutationResult> mutationResults = result.mutationResults;
445 .mutationResult 367 assert(autoIdStartIndex != -1);
446 .insertAutoIdKeys 368 assert(mutationResults.length >=
447 .map(_convertApi2DatastoreKey).toList(); 369 (autoIdStartIndex + autoIdInserts.length));
370 keys = mutationResults
371 .skip(autoIdStartIndex)
372 .take(autoIdInserts.length)
373 .map((api.MutationResult r) => _convertApi2DatastoreKey(r.key))
374 .toList();
448 } 375 }
449 return new datastore.CommitResult(keys); 376 return new datastore.CommitResult(keys);
450 }, onError: _handleError); 377 }, onError: _handleError);
451 } 378 }
452 379
453 Future<List<datastore.Entity>> lookup(List<datastore.Key> keys, 380 Future<List<datastore.Entity>> lookup(List<datastore.Key> keys,
454 {datastore.Transaction transaction}) { 381 {datastore.Transaction transaction}) {
455 var apiKeys = keys.map((key) { 382 var apiKeys = keys.map((key) {
456 return _convertDatastore2ApiKey(key, enforceId: true); 383 return _convertDatastore2ApiKey(key, enforceId: true);
457 }).toList(); 384 }).toList();
458 var request = new api.LookupRequest(); 385 var request = new api.LookupRequest();
459 request.keys = apiKeys; 386 request.keys = apiKeys;
460 if (transaction != null) { 387 if (transaction != null) {
461 // TODO: Make readOptions more configurable. 388 // TODO: Make readOptions more configurable.
462 request.readOptions = new api.ReadOptions(); 389 request.readOptions = new api.ReadOptions();
463 request.readOptions.transaction = (transaction as TransactionImpl).data; 390 request.readOptions.transaction = (transaction as TransactionImpl).data;
464 } 391 }
465 return _api.datasets.lookup(request, _project).then((response) { 392 return _api.projects.lookup(request, _project).then((response) {
466 if (response.deferred != null && response.deferred.length > 0) { 393 if (response.deferred != null && response.deferred.length > 0) {
467 throw new datastore.DatastoreError( 394 throw new datastore.DatastoreError(
468 'Could not successfully look up all keys due to resource ' 395 'Could not successfully look up all keys due to resource '
469 'constraints.'); 396 'constraints.');
470 } 397 }
471 398
472 // NOTE: This is worst-case O(n^2)! 399 // NOTE: This is worst-case O(n^2)!
473 // Maybe we can optimize this somehow. But the API says: 400 // Maybe we can optimize this somehow. But the API says:
474 // message LookupResponse { 401 // message LookupResponse {
475 // // The order of results in these fields is undefined and has no rela tion to 402 // // The order of results in these fields is undefined and has no rela tion to
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 datastore.Transaction transaction}) { 454 datastore.Transaction transaction}) {
528 // NOTE: We explicitly do not set 'limit' here, since this is handled by 455 // NOTE: We explicitly do not set 'limit' here, since this is handled by
529 // QueryPageImpl.runQuery. 456 // QueryPageImpl.runQuery.
530 var apiQuery = new api.Query() 457 var apiQuery = new api.Query()
531 ..filter = _convertDatastore2ApiFilters(query.filters, 458 ..filter = _convertDatastore2ApiFilters(query.filters,
532 query.ancestorKey) 459 query.ancestorKey)
533 ..order = _convertDatastore2ApiOrders(query.orders) 460 ..order = _convertDatastore2ApiOrders(query.orders)
534 ..offset = query.offset; 461 ..offset = query.offset;
535 462
536 if (query.kind != null) { 463 if (query.kind != null) {
537 apiQuery.kinds = [new api.KindExpression()..name = query.kind]; 464 apiQuery.kind = [new api.KindExpression()..name = query.kind];
538 } 465 }
539 466
540 var request = new api.RunQueryRequest(); 467 var request = new api.RunQueryRequest();
541 request.query = apiQuery; 468 request.query = apiQuery;
542 if (transaction != null) { 469 if (transaction != null) {
543 // TODO: Make readOptions more configurable. 470 // TODO: Make readOptions more configurable.
544 request.readOptions = new api.ReadOptions(); 471 request.readOptions = new api.ReadOptions();
545 request.readOptions.transaction = (transaction as TransactionImpl).data; 472 request.readOptions.transaction = (transaction as TransactionImpl).data;
546 } 473 }
547 if (partition != null) { 474 if (partition != null) {
548 request.partitionId = new api.PartitionId() 475 request.partitionId = new api.PartitionId()
549 ..namespace = partition.namespace; 476 ..namespaceId = partition.namespace;
550 } 477 }
551 478
552 return QueryPageImpl.runQuery(_api, _project, request, query.limit) 479 return QueryPageImpl.runQuery(_api, _project, request, query.limit)
553 .catchError(_handleError); 480 .catchError(_handleError);
554 } 481 }
555 482
556 Future rollback(datastore.Transaction transaction) { 483 Future rollback(datastore.Transaction transaction) {
557 // TODO: Handle [transaction] 484 // TODO: Handle [transaction]
558 var request = new api.RollbackRequest() 485 var request = new api.RollbackRequest()
559 ..transaction = (transaction as TransactionImpl).data; 486 ..transaction = (transaction as TransactionImpl).data;
560 return _api.datasets.rollback(request, _project).catchError(_handleError); 487 return _api.projects.rollback(request, _project).catchError(_handleError);
561 } 488 }
562 } 489 }
563 490
564 class QueryPageImpl implements Page<datastore.Entity> { 491 class QueryPageImpl implements Page<datastore.Entity> {
565 static const int MAX_ENTITIES_PER_RESPONSE = 2000; 492 static const int MAX_ENTITIES_PER_RESPONSE = 2000;
566 493
567 final api.DatastoreApi _api; 494 final api.DatastoreApi _api;
568 final String _project; 495 final String _project;
569 final api.RunQueryRequest _nextRequest; 496 final api.RunQueryRequest _nextRequest;
570 final List<datastore.Entity> _entities; 497 final List<datastore.Entity> _entities;
(...skipping 14 matching lines...) Expand all
585 int batchLimit = batchSize; 512 int batchLimit = batchSize;
586 if (batchLimit == null) { 513 if (batchLimit == null) {
587 batchLimit = MAX_ENTITIES_PER_RESPONSE; 514 batchLimit = MAX_ENTITIES_PER_RESPONSE;
588 } 515 }
589 if (limit != null && limit < batchLimit) { 516 if (limit != null && limit < batchLimit) {
590 batchLimit = limit; 517 batchLimit = limit;
591 } 518 }
592 519
593 request.query.limit = batchLimit; 520 request.query.limit = batchLimit;
594 521
595 return api.datasets.runQuery(request, project).then((response) { 522 return api.projects.runQuery(request, project).then((response) {
596 var returnedEntities = const []; 523 var returnedEntities = const [];
597 524
598 var batch = response.batch; 525 var batch = response.batch;
599 if (batch.entityResults != null) { 526 if (batch.entityResults != null) {
600 returnedEntities = batch.entityResults 527 returnedEntities = batch.entityResults
601 .map((result) => result.entity) 528 .map((result) => result.entity)
602 .map(DatastoreImpl._convertApi2DatastoreEntity) 529 .map(DatastoreImpl._convertApi2DatastoreEntity)
603 .toList(); 530 .toList();
604 } 531 }
605 532
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 return new Future.sync(() { 628 return new Future.sync(() {
702 throw new ArgumentError('Cannot call next() on last page.'); 629 throw new ArgumentError('Cannot call next() on last page.');
703 }); 630 });
704 } 631 }
705 632
706 return QueryPageImpl.runQuery( 633 return QueryPageImpl.runQuery(
707 _api, _project, _nextRequest, _remainingNumberOfEntities) 634 _api, _project, _nextRequest, _remainingNumberOfEntities)
708 .catchError(DatastoreImpl._handleError); 635 .catchError(DatastoreImpl._handleError);
709 } 636 }
710 } 637 }
OLDNEW
« no previous file with comments | « lib/db.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698