|No such thing as a small change|
Class::DBI - performing action on column before it is used or savedby duct_tape (Hermit)
|on Dec 19, 2003 at 20:29 UTC||Need Help??|
duct_tape has asked for the wisdom of the Perl Monks concerning the following question:
I used to use a custom inhouse Object-Relation mapping module that a previous employee developed, but have been recently looking into Class::DBI. The old module did not support relationships between tables, and I really like this feature of Class::DBI. The interface was also a bit kludgy. One thing that it did have was the ability to have 'presave' and 'postload' methods for each column.
I have a database that stores passwords encrypted with Blowfish. I would use the postload method to decrypt it as soon as it was read, and then the presave method to encrypt it so that it was written back to the database encrypted.
I am trying to mimic this behavior in Class::DBI and I am getting stuck. I want it to be done as transparently as possible.
Here are the things I have tried so far:
* Overriding 'password' accessor. However this doesn't work when it comes to create()'ng so the password is stored plaintext in the database.
* Overriding normalize_column_values() to encrypt the password, and then having the accessor decrypt the password. This worked for the most part, except that it was an ugly hack and find_or_create() didn't work because normalize_column_values() wasn't called until after the search.
* Using triggers for 'select', 'before_create', and 'before_update'. This worked about as well as above. create()'s and retrieve()'s worked but find_or_create() failed due to the triggers not being called yet.
* Using a has_a relationship for 'password' and a custom EncryptedPassword class. I can't get this to work properly though. When using create() the class is 'inflated' using the plaintext password, otherwise it is called with the encrypted password and I am not sure how to tell how the constructor for the custom class was called.
This method seems like the best bet though, as looking through the CDBI code searching 'deflates' has_a relationships automatically. I'm just not completely sure how to go about writing this class.
If you'd like to see some example code of what I am trying to do let me know. I am using MySQL for my database, so triggers/stored procedures at the database level are not an option.
Has anyone done anything similar to this? Tips, tricks, advice? I am relatively new to Class::DBI, and so far I am very impressed with it. I just can't seem to get over this hurdle. :(
I was thinking I could change how the _do_search method in CDBI works so that it calls triggers first, but I am not real familiar with the codebase yet and I want to make sure that I am not overlooking something obvious.
I've also asked this on the cdbi-talk mailing list, but I thought I would post here as well to see if I could get some other ideas.
Bradley C Bailey