I had the opportunity to mess around with this a little bit, and sort
of hacked in something for Structs, anyway.
I'm sure this is completely NOT the way it should be done, but I just
wanted to see if it worked.
I added a couple methods to cfStructData.java:
public Entity toEntity() throws cfmRunTimeException
{
if(entity == null)
throw newCfmRunTimeException("You must generate a key
and assign it
before returning an entity.");
return entity;
}
public Entity toEntity(Key key) throws cfmRunTimeException
{
Entity entity = null ;
if (this.entity == null) {
entity = entity = new Entity(key);
googleClearProperties(entity);
googleSetProperties(entity);
this._googleKey = key;
this.entity = entity;
} else {
entity = this.entity;
}
return entity;
}
The idea is that you could take a struct and pre-set the key
(generated by a keybuilder) - this allows the entity to be a child
entity of another entity (see entity groups in GAE docs).
An example usage might be:
<cfscript>
message = structNew();
message['sender'] = 5; // Sender's ID
message['message'] = "This is a 140 character or less message";
recipentList = structNew();
recipentList['recipients'] = ArrayNew(1);
recipentList['recipients'][1] = 46;
recipentList['recipients'][2] = 24;
recipentList['recipients'][3] = 67;
recipentList['recipients'][4] = 30;
recipentList['recipients'][5] = 22;
recipentList['recipients'][6] = 11;
recipentList['recipients'][7] = 54;
recipentList['recipients'][8] = 99;
// Get a KeyFactory
keyFactory =
createObject("java","com.google.appengine.api.datastore.KeyFactory");
</cfscript>
<!--- Persist the entities --->
<cfset messageKey = message.googleWrite("message")>
<!--- Get a KeyBuilder for the message I just persisted --->
<cfset messageBuilder =
createObject("java","com.google.appengine.api.datastore.KeyFactory
$Builder").init(keyFactory.stringToKey(messageKey))>
<!--- Generate a Child Key --->
<cfset childKey =
messageBuilder.addChild("messageRecipientList","someId").getKey()>
Child Key: <cfdump var="#childKey.toString()#"><br>
<!--- Turn the struct into an entity with the childKey I just created.
--->
<cfset messageRecipientList = recipentList.toEntity(childKey)>
<!--- Write the Entity - we use the null argument function because we
already populated the entity and key with the toEntity function --->
<cfset recipentListKey = recipentList.googleWrite()>
RecipentKey: <cfdump
var="#keyFactory.stringToKey(recipentListKey).toString()#"><br>
<!--- Test to see if it has the right parent --->
RecipientList Parent: <cfdump
var="#keyFactory.keyToString(keyFactory.stringToKey(recipentListKey).getParent())#"><br>
<!--- Try loading the recipentList into a new variable --->
<cfset newRList = googleRead(recipentListKey)>
newRList: <cfdump var="#newRList#"><br>
<!--- Try turning this into an entity again --->
<cfset newRListEntity = newRList.toEntity()>
newRListEntity: <cfdump var="#newRListEntity#"><br>
Love to hear if anything like this is in the Roadmap for the GAE
version.
I think it would be very useful to be able to pre-set the key for a
Struct or CFC before persisting it to the App Engine - this would open
up the doors for a much more scalable datastore implementation for
power users.
I'd be willing to do the work here, but I'd need some guidance/reviews
from one of the architects on the actual, proper way to do this.
Thanks!
Edward Smith
--
Open BlueDragon Public Mailing List
http://www.openbluedragon.org/ http://twitter.com/OpenBlueDragon
mailing list - http://groups.google.com/group/openbd?hl=en
!! save a network - please trim replies before posting !!