Planning the new SQLBeans
Input please! :D
Since I've been finishing up the new Hydrogen templating engine, I've been thinking more about how I want to change SQLBeans, and I've put down a few pretty solid ideas I'm excited about. So I just want to cover the basics of what I'm planning for the new library, and I would love your feedback about whether you like it, whether any of your webapps need to do something that my new system won't support, and whether you've seen any other ORM or ORM-like solution that's better than what I've come up with.
So here's what I'm thinking.
Right now, if you want to narrow down the set of results you get from an SQLBean, you have to create a new instance of Query and put in a few WHERE clauses and pass that to the SQLBean. That is *messy*. The new system won't require you to use the Query library like that. Instead, if you want to retrieve all users in, for example, the group named Moderator, you might do this:
$users = UserBean::find()->group_name('Moderator');Or maybe you want to find all normal members with exactly one post:
$users = UserBean::find()->group_name('Members')->posts(1);Or maybe you want to do the same thing, but for members with more than 20 posts:
$users = UserBean::find()->group_name('Members')->posts_greaterThan(20);Or maybe you want to find just one user, change his name to "Fluffy", change his age to 6, and save that back to the database:
$user = UserBean::findOne()->username('Kyek');
$user->username = 'Fluffy';
$user->age = 6;Done. No calling update(), no multiple queries, you just change what you need to change, and when you're done making changes, it saves back to the database.
You can also update many users at once. This line will promote all Moderators to Administrators:
$users = UserBean::find()->group_name('Moderators');
$users->group_name = 'Administrators';Again, no calling update(), and this is just one SQL query. You can also pull this off in one line:
UserBean::find()->group_name('Moderators')->group_name = 'Administrators';Here's another improvement over SQLBeans, too: deleting records. You could always select a record from the database and THEN delete it, like this (this will still work):
$user = UserBean::findOne()->username('magik');
$user->delete();...but the drawback is, you're running a SELECT query before you run a DELETE query, and all we wanted to do was delete it. So now, you can do this and it will never execute a SELECT query:
UserBean::findOne()->username('magik')->delete();What's more, you can use the same concept to mass-delete a group of records without selecting them first:
UserBean::find()->group_name('Banned')->delete();And check out how easy it is to create a record now. Actually, there will probably be two ways. Here's the long way:
$newUser = UserBean::create(); $newUser->username = "Kyek"; $newUser->email = "kyek@webdevrefinery.com"; $newUser->age = 26; $newUser->group_name = 'Administrators'; // Note: This will actually set the group_id field of this record in the 'users' table to the id number of 'Administrators' in the groups table, all with ONE QUERY!
And done. Again, no insert() or update() or anything like that.
But check out the short way:
UserBean::create()
->username('Kyek')
->email('kyek@webdevrefinery.com')
->age(26)
->group_name('Administrators');One line, and done.
A few notes that my examples here haven't illustrated:
- The 'find' command will take two optional arguments: the first will be the max number of records to get (so find(1) and findOne() will actually be the exact same thing), and the second will be a combination of what the current SQLBeans' doMapping and mapOverride arguments do now. They'll allow you to get just a subset of columns rather than the whole record, and it will also allow you to specify whether the mapped tables should be JOINed and SELECTed as well.
- No more getMapped() is required. You just prefix your function names. So UserBean::find()->group_name('Members') will first check to see if there's a field named "group_name" in the Users table, and if not, it'll look for a field named 'name' in the 'Groups' table. My whole concept here is that SQLBeans should be smart enough to know what you want without you having to be ridiculously verbose about telling it.
- If for some reason you need to force an updated or created record to save back to the database before Hydrogen detects that you're done changing it, you can call ->save() on any bean instance.
- I haven't decided how SQLBeans finds out about your database structure yet. I will not do what most ORMs do and force you to give up control of your database structure. That is crap. You'll either define your tables much like SQLBeans already does, or I might move to some sort of XML-based file that tells Hydrogen what your tables and fields and stuff are. Either way, I'd **LOVE** to make it possible for you to call one method and have all of your tables created in the database, making new installs a breeze. That's not my highest priority though.
Anyway, sorry, I know this was long, but I'd love to get your thoughts. Note that I'm not trying to make this something that completely removes the need for executing your own queries. That's what makes ORMs so damn heavy. Sometimes you'll need to write your own queries, and that's ok. But what I'm trying to do is make your life as easy as possible, 95% of the time ;-)






Cartoon Clouds
Mountains
Sunrise
Clouds
Green Clouds
None




















Help