Auto_Record provides an easy way to create object intefaces to your tables. How it works is you create your own custom type and name it the singular version of your table name. The new type would be a sub-type, or sub-class, of Auto_Record. When the Type is created, the Auto_Record onCreate call back function will automatically read in your database fields and assign their values to the local variables you have created in your sub-type with the same name. You can then update your fields by using the set_ functions also provided by Auto_Record. Saving is done by calling ->save, deleting is done by calling ->delete, and so on.
Auto_Record also gives you the ability to overload parent functions, like ->save and ->load, so that you can have absolute control over your data coming back from your table. An example of this is when you call ->delete, you want to delete from multiple joined tables before, or after, you actually delete the row from the original table. This can be done simply by creating your own ->delete function in the sub-type which would do what you need to have done, but then you can call the original ->delete function after that to finish the job.
The idea of Auto_Record is somewhat based on experiences I've had with Ruby's Active Record where a row is manipulated through a sub-classed object. It saves time because you don't have to write a lot of inlines from scratch, and it's very quick to set up a new type for a table.
Because Auto_Record is basically a small framework or methodology, for best results you should follow the ideas behind Auto_Record in your development:
- Tables should be named the plural of what they contain. For example, if
you are storing users, then the table would be called users, not user.
Note how it's plural. Your sub-type based off Auto_Record would be called
user, instead of users.
- Because of how namespaces work in Lasso, it's best that you don't use
underscores in your table name because self->type may not return all of
the sub-type name depending on how you have your type set up. This can be
worked around by setting your own custom table name using
->set_dbtablename( 'my_table' ).
- Tables names are always treated as lowercase by Auto_Record, but again can
be worked around by following the previous item.
- Auto_Record requires that the primary key of the table be called `id`,
there's no work around for this other than modifying Auto_Record's code.
- the column `dbtablename` cannot be used as it's reserved by Auto_Record.
The property dbtablename is named as such because it's unlikely anyone is
using that inside their own tables.
- Auto_Record only specifies the -Table parameter in the Inlines it uses.
This means you need to wrap your Auto_Record code in an inline that
specifies it's own -Database name. If no database name is found,
Auto_Record will throw a fatal error during the onCreate phase.
- Boolean types are stored as 0 and 1 in the table for false ant true
respectively. Note: this means that set_enabled( true ) will store as 1 in
the table, but set_enabled( 'true' ) will store as 'true' in the table
because 'true' is not a boolean type.
Important member tags, and what they do:
->load - Takes an integer value for the id and tries to look it up in the
table. If found, it will load all the fields in to the type local
variables and return true. If not found, it will return false.
->load_from_array - Takes a string value for the field name, and a secondary
value of any time to search the database with. If found, it will populate
the local variables from the fields and return true, but if not it will
return false.
->load_from_sql - Same as load_from_field but takes a string value that is a
SQL query and will load the type properties based on the results of the
query and return true. If not found, it will return false.
->save - Will save the current properties in the type to the table row. If a
container type is provided (eg: Array, Map, etc) it will use those values
to save instead of the set properties. This allows you to only update what
you want. If when saving no id has been set, a new row will be creatd in
the table, otherwise it will update the row identified by the id. If
everything worked, it will return true. If not, it will return false.
->delete - Will delete the row in the table identified by the value of the
id property set in the type.
->set_dbtablename - Takes a string value that is the new table name to use
in the type.
->set_id - Takes an integer value that is the new ID of the row. Note: this
does not reload the type, but only sets the id. Be careful with this one.
->get_... - A get_... function is available for all properties of the type
that you have set up. by default, you have access to id and dbtablename,
but if you set up your own local variables in your sub-type, you would be
able to access them with the get_... tag. An example of this is if you
have a username property, then you can call get_username to return the
value. Note that if the property does not exist an error will be thrown.
->set_... - Similar to how the get_... tag works based on the properties
that have been set up. The set_... tag will take one parameter of any
type, and set the value of the property to that value. Because there's no
validation of the input type, it's recommended that if you need to have
validation that you create your own custom set_... tag in your type that
does what you want it to. Your own set_... tag will override the automatic
set_... tag.
Troubleshooting:
- If you are having troubles getting your code to work make sure that you
check error_code and error_msg to seee that you are not getting weird
results back from your table.
- All Auto_Record member tags will return true or false unless they are
designed to return something else. It's always safe to check for false
(except on getters) even if you are expecting something other than a
boolean value. Built in setters do not return true because they will
always be true, which makes it pointless.
Tricks:
- If you name a property and end it with a underscore (_) that property will
NOT be included whenever a save operation is performed, unless that save
operation is being populated by a container.
- If you just print out the sub-class, it will print the value of the id.
- You can compare the type to an integer. This means that if the type has
not been loaded from the table, it will evaluate to false, and if the type
has been loaded from the table, it will evaluate to true.
Installation:
Take the Auto_Record code and save it into a file called Auto.lasso. Move this Auto.lasso file into the LassoLibraries folder of your Lasso Professional 8 folder, or the LassoLibraries folder of your Lasso site.
Version:
1.1 (2008-03-27)
Parameters
-ID
integer, optional
When creating an object the id, if specified, will load that row out of the table.
Sample Usage
Table Schema:
create table users
(
id int(10) unsigned not null primary key auto_increment,
username varchar(255) not null,
password varchar(255) not null,
firstname varchar(255) not null,
lastname varchar(255) not null,
email varchar(255) not null,
unique u_username (username ),
key (firstname),
key (lastname),
key (email )
) engine=MyISAM charset=UTF8;
Code based on schema above:
[
define_type( 'user', 'auto_record' );
local(
'username' = null,
'password' = null,
'firstname' = null,
'lastname' = null,
'email' = null );
/define_tag;
var( 'user' = user );
$user->set_username( 'newuser' );
$user->set_password( 'newpassword' );
$user->set_firstname( 'first name' );
$user->set_lastname( 'last name' );
$user->set_email( 'here@there.com' );
if( $user->save );
'Successfully created new user<br>';
'New user id is: ' $user->get_id; '<br>';
else;
'Error: '; error_code; ': '; error_msg; '<br>';
/if;
]
Source Code
Click the "Download" button below to retrieve a copy of this tag,
including the complete documentation and sample usage shown
on this page. Place the downloaded ".inc" file in your
LassoStartup folder, restart Lasso, and you can begin using this
tag immediately.
Auto.lasso.zip (4.96 kb)
Comments
03/27/2008, Adam Randall Upgrading
If you need to reload the Auto namespace, you can do so with this code here:
namespace_unload( '_global_Auto_' );
namespace_load( '_global_Auto_' );
Upgrading
If you need to reload the Auto namespace, you can do so with this code here: namespace_unload( '_global_Auto_' ); namespace_load( '_global_Auto_' );