Based on my experience building custom, app-specific generators, what
I've liked, disliked, and considered...

A generator should be able to be rerun at arbitrary times and update
the CRUD part without affecting anything else.  It should create beans
that have getters/setters for properties.  It should allow custom
mappings between table names and entity names (i.e. I can say a table
called 'mytable' maps to an entity called 'TableDeMoi').

There should be some automated translation for underscore_separated
names to camelCase names, both for entities and fields.  Surrogate
primary keys should always be translated to 'id' properties on
entities (i.e. person.person_id maps to Person.getId()).  Both of
these should be optional/customizable if you're distributing.

Methods should be smart enough to only do something when needed.  So
if I load an entity and then immediately call save(), nothing should
happen, since the entity's properties haven't been changed.  There
should be a 'save' method, which will intelligently insert or update,
ideally only the modified fields on updates.

Beans should have a constructor that accepts full instance data as
args.  Beans should automatically have basic validation coded by the
generator.  I.e. INT fields can automatically check for integer-ness,
varchar fields can be checked for length restrictions, etc.  That
should be easily extensible by the app developer, of course, without
affecting the ability to regenerate if the DB schema changes.

Beans should have getMemento and setMemento methods that allow for
serializing the object state.  According to the DP, the memento should
be opaque (usually an inner class), but CF doesn't afford that very
easily, so non-opaque is fine with me.  Whatever that memento is, it
should be trivially serialized/deserialized, or some other means of
serializing/deserializing should be exposed.

Some entity relationship support would be ideal, based on DB foreign
keys.  I.e. if the 'car' table has an 'ownerId' field that references
person.id, there should be getOwner:Person and setOwner(Person):void
methods, and probably getOwnerId:int and setOwnerId(int):void methods
as well.  Ideally the Person object would have getCarList, addCar, and
removeCar methods as well, but that's harder to autogenerate, unless
you're doing the whole schema at once, rather than a single
entity/table.

And then the holy grail: many-to-many relationship support.  I'd be
happy with forcing the 'link' table to be it's own implicit entity, as
long as the two 'real' entities are smart enough to have direct access
to the other 'real' entity.  I.e. the link table entity is an exposed
implementation detail.  For example, people own cars, cars are owned
by people.  Person, Car, and CarOwnership entities with
Person.getCarList, Car.getOwnerList, and CarOwnership.getPerson
methods, along with their supporting methods.

Updates to relationships need to be clearly documented, as does the
effect of calling save on an entity with modified related objects. 
Propogation is good, but should be disable-able at some level or
another.

I'd hope to see factory/managers for the beans so they're easy to use.
 Aside from getPersonById, and getNewPerson, also have
createPerson(name, dob, ...), deletePerson(id), and updatePerson(id,
name, dob...) for calling from your UI(s).  This would also be the
place for doing caching and lazy loading in an encapsulated way.  If
you cache, hooks should be exposed that can be used for syncing across
a cluster (the sync stuff would be built by the app developer and
utilize the hooks).

Some recognition of concurrency issues should be made, even if it's
just to explicitly say "you're on your own".  Smart updates (i.e. only
updating modified fields) goes a long way to mitigating this issue,
but doesn't address it completely.  For example UPDATE table SET f = f
+ 1 WHERE id = 3; is atomic, but t=getTById(3);t.setF(t.getF() +
1);t.save(); is not atomic.  Concurrency issues don't exist with the
former, but do with the latter, unless the whole thing is in a
transaction.  That's a restriction this type of code can't enforce,
but a well designed application will likely exhibit that behaviour so
if clearly documented, I'd say it's reasonable to assume.

Of course, there are sound arguments against this sort of thing at
all.  It's a delecate balance between using a tool to help you do your
job, and relying on a tool because you can't really do your job.  I'm
all for using them until you've got a sound reason not to, though.

cheers,
barneyb

On 11/8/05, John C. Bland II <[EMAIL PROTECTED]> wrote:
> What is it "everyone" looks for in a CRUD generator? I see some folks saying
> they'd like to see best practices, some want getters/setters, and others
> just want a function you pass everything too.
>
> Just a little reserach...
>
> --
> John C. Bland II
> "I do what I can do when I can do it." - Chris Tucker, Money Talks
>

--
Barney Boisvert
[EMAIL PROTECTED]
360.319.6145
http://www.barneyb.com/

Got Gmail? I have 100 invites.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Find out how CFTicket can increase your company's customer support 
efficiency by 100%
http://www.houseoffusion.com/banners/view.cfm?bannerid=49

Message: http://www.houseoffusion.com/lists.cfm/link=i:4:223650
Archives: http://www.houseoffusion.com/cf_lists/threads.cfm/4
Subscription: http://www.houseoffusion.com/lists.cfm/link=s:4
Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Donations & Support: http://www.houseoffusion.com/tiny.cfm/54

Reply via email to