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 !!

Reply via email to