Friday, October 10, 2008

PrimeBase PBMS does MYISAM

Hi,

I just pushed a version of PBMS up onto launchPad that works with any storage engine. 

The new version provides a set of UDFs and API functions that allow you to set triggers on longblob columns so that the table can be used with the PBMS engine the same way a PBXT table would.  

The following has been added to the API:


/* Functions used for non PBMS enabled tables. */

/*

 * pbms_init_udfs() 

 * Declares the PBMS UDFs on the server if they do not already exist.

 *

 * Equivalent UFD: NONE

 */

pbms_bool pbms_init_udfs(MYSQL *mysql);


/*

 * pbms_enabled() 

 * Returns 'true' if the 'engine' is PBMS enabled i.e. provides direct support for PBMS. 

 * So far the PBXT engine is the only PBMS enabled engine out there. Hopefully that will change.

 *

 * Equivalent UFD: pbms_enabled_engine(engine)

 */

pbms_bool pbms_enabled(MYSQL *mysql, const char *engine, pbms_bool *enabled);


/*

 * pbms_init_table() 

 * Creates triggers on any 'longblob' columns in the table that will notify the PBMS engine when blob PBMS  

 * references are inserted, deleted, or updated. If 'no_blobs_ok' is 'false' then an error is reported if 

 * no 'longblob' columns are found. If 'no_blobs_ok' is 'true' and then no error is reported if no 'longblob'

 * columns are found and no action is taken.

 *

 * Equivalent UFD: NONE

 */

pbms_bool pbms_init_table(struct st_mysql *mysql, const char *database, const char *table, pbms_bool no_blobs_ok);


/*

 * pbms_reset_table_blobs() 

 * This is similar to  pbms_init_table() except that it is meant to be called if an alter table has been done on

 * a table that contains blobs being managed by PBMS and either a 'longblob' column has been added or dropped, or

 * the ordinal position of a 'longblob' column has changed.

 *

 * Equivalent UFD: NONE

 */

pbms_bool pbms_reset_table_blobs(struct st_mysql *mysql, const char *database, const char *table);


/*

 * pbms_drop_table_blobs() 

 * This function is called after a table has been dropped to notify PBMS to remove all blob references from that

 * table.

 *

 * Equivalent UFD: pbms_delete_all_blobs_in_table(database);

 */

pbms_bool pbms_drop_table_blobs(struct st_mysql *mysql, const char *database, const char *table);


/*

 * pbms_table_renamed() 

 * This function is called after a table containing blobs has been renamed.

 *

 * Equivalent UFD: pbms_rename_table_with_blobs(database);

 */

pbms_bool pbms_table_renamed(struct st_mysql *mysql, const char *database, const char *old_table, const char *new_table);


/*

 * pbms_dropping_database() 

 * Call this function before dropping any database that contained tables containing blobs. This gives the PBMS

 * engine a chance to remove it's files and sub directories from the database directory so that it can be

 * deleted.

 *

 * Equivalent UFD: pbms_dropping_database(database);

 */

pbms_bool pbms_dropping_database(struct st_mysql *mysql, const char *database);


/*

User defined functions provided with the PBMS engine:


//UDFs used in triggers: 

// 'col_position' is the ordinal of the longblob column starting at position 1.

pbms_insert_blob_trig(database, table col_position, blob_url);

pbms_update_blob_trig(database, table col_position, old_blob_url, new_blob_url);

pbms_delete_blob_trig(database, table col_position, blob_url);


// Example:

crete table x.foo(c1 int, c2 longblob);

create trigger x.foo_insert_trig  BEFORE INSERT on x.foo for each row BEGIN set NEW.c2 = pbms_insert_blob_trig("x", "foo", 2, NEW.c2); END

create trigger x.foo_update_trig  BEFORE UPDATE on x.foo for each row BEGIN set NEW.c2 = pbms_update_blob_trig("x", "foo", 2, OLD.c2, NEW.c2); END

create trigger x.foo_delete_trig  BEFORE UPDATE on x.foo for each row BEGIN declare dummy integer; set dummy = pbms_delete_blob_trig("x", "foo", 2, OLD.c2); END

///////////


pbms_delete_all_blobs_in_table(database, table);

pbms_rename_table_with_blobs(database, old_table, new_table);

pbms_dropping_database(database);

pbms_enabled_engine(engine);

NOTE: pbms_enabled_engine() returns -1 on error.


CREATE FUNCTION pbms_insert_blob_trig RETURNS STRING SONAME "libpbms.so";

CREATE FUNCTION pbms_update_blob_trig RETURNS STRING SONAME "libpbms.so";

CREATE FUNCTION pbms_delete_blob_trig RETURNS INTEGER SONAME "libpbms.so";

CREATE FUNCTION pbms_delete_all_blobs_in_table RETURNS INTEGER SONAME "libpbms.so";

CREATE FUNCTION pbms_rename_table_with_blobs RETURNS INTEGER SONAME "libpbms.so";

CREATE FUNCTION pbms_dropping_database RETURNS INTEGER SONAME "libpbms.so";

CREATE FUNCTION pbms_enabled_engine RETURNS INTEGER SONAME "libpbms.so";


*/


Use of  PBMS with non PBMS enabled engines is not yet transactionally safe. This means that if you use it on an INODB table while say doing some inserts in a transaction and then rollback the transaction the blob references will remain. Of course PBMS enabled engines such as PBXT do not have this problem. Making PBMS transactionally safe with non PBMS enabled engines is on my to-do list.

The test shell 'pbmstest' included with the PBMS source uses the new API functions and by default performs it's tests using a MYISAM table. 

I am currently working on getting the documentation updated with the new features and name change so that I can make an official release with this version.

Until then I invite anyone interested to grab a copy of the latest code from launchpad and play with it.

Barry

No comments: