AstronDatabaseInterface: Add support for querying specific fields of an object
This commit is contained in:
parent
411d15c275
commit
804fa563f5
|
|
@ -20,6 +20,7 @@ class AstronDatabaseInterface:
|
|||
self.air = air
|
||||
|
||||
self._callbacks = {}
|
||||
self._dclasses = {}
|
||||
|
||||
def createObject(self, databaseId, dclass, fields={}, callback=None):
|
||||
"""
|
||||
|
|
@ -73,7 +74,7 @@ class AstronDatabaseInterface:
|
|||
|
||||
del self._callbacks[ctx]
|
||||
|
||||
def queryObject(self, databaseId, doId, callback):
|
||||
def queryObject(self, databaseId, doId, callback, dclass=None, fieldNames=()):
|
||||
"""
|
||||
Query object `doId` out of the database.
|
||||
|
||||
|
|
@ -85,21 +86,44 @@ class AstronDatabaseInterface:
|
|||
# Save the callback:
|
||||
ctx = self.air.getContext()
|
||||
self._callbacks[ctx] = callback
|
||||
self._dclasses[ctx] = dclass
|
||||
|
||||
# Generate and send the datagram:
|
||||
dg = PyDatagram()
|
||||
dg.addServerHeader(databaseId, self.air.ourChannel, DBSERVER_OBJECT_GET_ALL)
|
||||
|
||||
if not fieldNames:
|
||||
dg.addServerHeader(databaseId, self.air.ourChannel,
|
||||
DBSERVER_OBJECT_GET_ALL)
|
||||
else:
|
||||
# We need a dclass in order to convert the field names into field IDs:
|
||||
assert dclass is not None
|
||||
|
||||
if len(fieldNames) > 1:
|
||||
dg.addServerHeader(databaseId, self.air.ourChannel,
|
||||
DBSERVER_OBJECT_GET_FIELDS)
|
||||
else:
|
||||
dg.addServerHeader(databaseId, self.air.ourChannel,
|
||||
DBSERVER_OBJECT_GET_FIELD)
|
||||
|
||||
dg.addUint32(ctx)
|
||||
dg.addUint32(doId)
|
||||
if len(fieldNames) > 1:
|
||||
dg.addUint16(len(fieldNames))
|
||||
for fieldName in fieldNames:
|
||||
field = dclass.getFieldByName(fieldName)
|
||||
if field is None:
|
||||
self.notify.error('Bad field named %s in query for'
|
||||
' %s object' % (fieldName, dclass.getName()))
|
||||
dg.addUint16(field.getNumber())
|
||||
self.air.send(dg)
|
||||
|
||||
def handleQueryObjectResp(self, di):
|
||||
def handleQueryObjectResp(self, msgType, di):
|
||||
ctx = di.getUint32()
|
||||
success = di.getUint8()
|
||||
|
||||
if ctx not in self._callbacks:
|
||||
self.notify.warning('Received unexpected DBSERVER_OBJECT_GET_ALL_RESP'
|
||||
' (ctx %d)' % (ctx))
|
||||
self.notify.warning('Received unexpected %s'
|
||||
' (ctx %d)' % (MsgId2Names[msgType], ctx))
|
||||
return
|
||||
|
||||
try:
|
||||
|
|
@ -108,14 +132,20 @@ class AstronDatabaseInterface:
|
|||
self._callbacks[ctx](None, None)
|
||||
return
|
||||
|
||||
dclassId = di.getUint16()
|
||||
dclass = self.air.dclassesByNumber.get(dclassId)
|
||||
if msgType == DBSERVER_OBJECT_GET_ALL_RESP:
|
||||
dclassId = di.getUint16()
|
||||
dclass = self.air.dclassesByNumber.get(dclassId)
|
||||
else:
|
||||
dclass = self._dclasses[ctx]
|
||||
|
||||
if not dclass:
|
||||
self.notify.error('Received bad dclass %d in'
|
||||
' DBSERVER_OBJECT_GET_ALL_RESP' % (dclassId))
|
||||
|
||||
fieldCount = di.getUint16()
|
||||
if msgType == DBSERVER_OBJECT_GET_FIELD:
|
||||
fieldCount = 1
|
||||
else:
|
||||
fieldCount = di.getUint16()
|
||||
unpacker = DCPacker()
|
||||
unpacker.setUnpackData(di.getRemainingBytes())
|
||||
fields = {}
|
||||
|
|
@ -127,7 +157,6 @@ class AstronDatabaseInterface:
|
|||
self.notify.error('Received bad field %d in query for'
|
||||
' %s object' % (fieldId, dclass.getName()))
|
||||
|
||||
|
||||
unpacker.beginUnpack(field)
|
||||
fields[field.getName()] = field.unpackArgs(unpacker)
|
||||
unpacker.endUnpack()
|
||||
|
|
@ -267,8 +296,10 @@ class AstronDatabaseInterface:
|
|||
def handleDatagram(self, msgType, di):
|
||||
if msgType == DBSERVER_CREATE_OBJECT_RESP:
|
||||
self.handleCreateObjectResp(di)
|
||||
elif msgType == DBSERVER_OBJECT_GET_ALL_RESP:
|
||||
self.handleQueryObjectResp(di)
|
||||
elif msgType in (DBSERVER_OBJECT_GET_ALL_RESP,
|
||||
DBSERVER_OBJECT_GET_FIELDS_RESP,
|
||||
DBSERVER_OBJECT_GET_FIELD_RESP):
|
||||
self.handleQueryObjectResp(msgType, di)
|
||||
elif msgType == DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP:
|
||||
self.handleUpdateObjectResp(di, False)
|
||||
elif msgType == DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP:
|
||||
|
|
|
|||
|
|
@ -233,6 +233,8 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
self.handleObjLocation(di)
|
||||
elif msgType in (DBSERVER_CREATE_OBJECT_RESP,
|
||||
DBSERVER_OBJECT_GET_ALL_RESP,
|
||||
DBSERVER_OBJECT_GET_FIELDS_RESP,
|
||||
DBSERVER_OBJECT_GET_FIELD_RESP,
|
||||
DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP,
|
||||
DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP):
|
||||
self.dbInterface.handleDatagram(msgType, di)
|
||||
|
|
|
|||
Loading…
Reference in New Issue