~nchohan/appscale/zk3.3.4

« back to all changes in this revision

Viewing changes to AppServer/google/appengine/api/datastore_admin.py

  • Committer: Navraj Chohan
  • Date: 2009-03-28 01:14:04 UTC
  • Revision ID: nchohan@cs.ucsb.edu-20090328011404-42m1w6yt60m6yfg3
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
# Copyright 2007 Google Inc.
 
4
#
 
5
# Licensed under the Apache License, Version 2.0 (the "License");
 
6
# you may not use this file except in compliance with the License.
 
7
# You may obtain a copy of the License at
 
8
#
 
9
#     http://www.apache.org/licenses/LICENSE-2.0
 
10
#
 
11
# Unless required by applicable law or agreed to in writing, software
 
12
# distributed under the License is distributed on an "AS IS" BASIS,
 
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
# See the License for the specific language governing permissions and
 
15
# limitations under the License.
 
16
#
 
17
 
 
18
"""The Python datastore admin API for managing indices and schemas.
 
19
"""
 
20
 
 
21
 
 
22
 
 
23
from google.appengine.api import api_base_pb
 
24
from google.appengine.api import apiproxy_stub_map
 
25
from google.appengine.api import datastore
 
26
from google.appengine.api import datastore_errors
 
27
from google.appengine.api import datastore_types
 
28
from google.appengine.datastore import datastore_index
 
29
from google.appengine.datastore import datastore_pb
 
30
from google.appengine.runtime import apiproxy_errors
 
31
from google.appengine.datastore import entity_pb
 
32
 
 
33
 
 
34
_DIRECTION_MAP = {
 
35
    'asc':        entity_pb.Index_Property.ASCENDING,
 
36
    'ascending':  entity_pb.Index_Property.ASCENDING,
 
37
    'desc':       entity_pb.Index_Property.DESCENDING,
 
38
    'descending': entity_pb.Index_Property.DESCENDING,
 
39
    }
 
40
 
 
41
 
 
42
def GetSchema(_app=None):
 
43
  """Infers an app's schema from the entities in the datastore.
 
44
 
 
45
  Note that the PropertyValue PBs in the returned EntityProtos are empty
 
46
  placeholders, so they may cause problems if you try to convert them to
 
47
  python values with e.g. datastore_types. In particular, user values will
 
48
  throw UserNotFoundError because their email and auth domain fields will be
 
49
  empty.
 
50
 
 
51
  Returns:
 
52
    list of entity_pb.EntityProto, with kind and property names and types
 
53
  """
 
54
  req = api_base_pb.StringProto()
 
55
  req.set_value(datastore_types.ResolveAppId(_app))
 
56
  resp = datastore_pb.Schema()
 
57
 
 
58
  _Call('GetSchema', req, resp)
 
59
  return resp.kind_list()
 
60
 
 
61
 
 
62
def GetIndices(_app=None):
 
63
  """Fetches all composite indices in the datastore for this app.
 
64
 
 
65
  Returns:
 
66
    list of entity_pb.CompositeIndex
 
67
  """
 
68
  req = api_base_pb.StringProto()
 
69
  req.set_value(datastore_types.ResolveAppId(_app))
 
70
  resp = datastore_pb.CompositeIndices()
 
71
  try:
 
72
    apiproxy_stub_map.MakeSyncCall('datastore_v3', 'GetIndices', req, resp)
 
73
  except apiproxy_errors.ApplicationError, err:
 
74
    raise datastore._ToDatastoreError(err)
 
75
 
 
76
  return resp.index_list()
 
77
 
 
78
 
 
79
def CreateIndex(index):
 
80
  """Creates a new composite index in the datastore for this app.
 
81
 
 
82
  Args:
 
83
    index: entity_pb.CompositeIndex
 
84
 
 
85
  Returns:
 
86
    int, the id allocated to the index
 
87
  """
 
88
  resp = api_base_pb.Integer64Proto()
 
89
  _Call('CreateIndex', index, resp)
 
90
  return resp.value()
 
91
 
 
92
 
 
93
def UpdateIndex(index):
 
94
  """Updates an index's status. The entire index definition must be present.
 
95
 
 
96
  Args:
 
97
    index: entity_pb.CompositeIndex
 
98
  """
 
99
  _Call('UpdateIndex', index, api_base_pb.VoidProto())
 
100
 
 
101
 
 
102
def DeleteIndex(index):
 
103
  """Deletes an index. The entire index definition must be present.
 
104
 
 
105
  Args:
 
106
    index: entity_pb.CompositeIndex
 
107
  """
 
108
  _Call('DeleteIndex', index, api_base_pb.VoidProto())
 
109
 
 
110
 
 
111
def _Call(call, req, resp):
 
112
  """Generic method for making a datastore API call.
 
113
 
 
114
  Args:
 
115
    call: string, the name of the RPC call
 
116
    req: the request PB. if the app_id field is not set, it defaults to the
 
117
      local app.
 
118
    resp: the response PB
 
119
  """
 
120
  if hasattr(req, 'app_id'):
 
121
    req.set_app_id(datastore_types.ResolveAppId(req.app_id(), 'req.app_id()'))
 
122
 
 
123
  try:
 
124
    apiproxy_stub_map.MakeSyncCall('datastore_v3', call, req, resp)
 
125
  except apiproxy_errors.ApplicationError, err:
 
126
    raise datastore._ToDatastoreError(err)
 
127
 
 
128
 
 
129
def IndexDefinitionToProto(app_id, index_definition):
 
130
  """Transform individual Index definition to protocol buffer.
 
131
 
 
132
  Args:
 
133
    app_id: Application id for new protocol buffer CompositeIndex.
 
134
    index_definition: datastore_index.Index object to transform.
 
135
 
 
136
  Returns:
 
137
    New entity_pb.CompositeIndex with default values set and index
 
138
    information filled in.
 
139
  """
 
140
  proto = entity_pb.CompositeIndex()
 
141
 
 
142
  proto.set_app_id(app_id)
 
143
  proto.set_id(0)
 
144
  proto.set_state(entity_pb.CompositeIndex.WRITE_ONLY)
 
145
 
 
146
  definition_proto = proto.mutable_definition()
 
147
  definition_proto.set_entity_type(index_definition.kind)
 
148
  definition_proto.set_ancestor(index_definition.ancestor)
 
149
 
 
150
  if index_definition.properties is not None:
 
151
    for prop in index_definition.properties:
 
152
      prop_proto = definition_proto.add_property()
 
153
      prop_proto.set_name(prop.name)
 
154
      prop_proto.set_direction(_DIRECTION_MAP[prop.direction])
 
155
 
 
156
  return proto
 
157
 
 
158
 
 
159
def IndexDefinitionsToProtos(app_id, index_definitions):
 
160
  """Transform multiple index definitions to composite index records
 
161
 
 
162
  Args:
 
163
    app_id: Application id for new protocol buffer CompositeIndex.
 
164
    index_definition: A list of datastore_index.Index objects to transform.
 
165
 
 
166
  Returns:
 
167
    A list of tranformed entity_pb.Compositeindex entities with default values
 
168
    set and index information filled in.
 
169
  """
 
170
  return [IndexDefinitionToProto(app_id, index)
 
171
          for index in index_definitions]
 
172
 
 
173
 
 
174
def ProtoToIndexDefinition(proto):
 
175
  """Transform individual index protocol buffer to index definition.
 
176
 
 
177
  Args:
 
178
    proto: An instance of entity_pb.CompositeIndex to transform.
 
179
 
 
180
  Returns:
 
181
    A new instance of datastore_index.Index.
 
182
  """
 
183
  properties = []
 
184
  proto_index = proto.definition()
 
185
  for prop_proto in proto_index.property_list():
 
186
    prop_definition = datastore_index.Property(name=prop_proto.name())
 
187
    if prop_proto.direction() == entity_pb.Index_Property.DESCENDING:
 
188
      prop_definition.direction = 'descending'
 
189
    properties.append(prop_definition)
 
190
 
 
191
  index = datastore_index.Index(kind=proto_index.entity_type(),
 
192
                                properties=properties)
 
193
  if proto_index.ancestor():
 
194
    index.ancestor = True
 
195
  return index
 
196
 
 
197
def ProtosToIndexDefinitions(protos):
 
198
  """Transform multiple index protocol buffers to index definitions.
 
199
 
 
200
  Args:
 
201
    A list of entity_pb.Index records.
 
202
  """
 
203
  return [ProtoToIndexDefinition(definition) for definition in protos]