In addition to mapping database rows to instance variables or to an objects data, EOAttribute objects can also alter how database values are selected, inserted, and updated. This is accomplished by defining special format strings for particular attributes. These format strings allow an application to extend its reach down to the database server for certain operations. These operations are then performed by the database server, which may or may not be advantageous to your application.
Using a custom read format (for SELECT operations), you can create a kind of derived attribute without defining the attribute as derived. For example, rather than defining a derived attribute to calculate an employees annual salary based on monthly salary multiplied by twelve, you can derive this value by setting the read format to the same SQL string youd use were you to declare the definition for a derived attribute. The advantage of using custom read formats over derived attributes is that you can easily write the derived value back to the data source by including a complimentary write format.
The difference between attributes that are declared to be
derived and attributes that are derived from custom read formats
is that the latter performs an operation on itself whereas derived
attributes operate on values in other attributes, often aggregating
them or otherwise modifying them. So, whereas the definition of
a derived attribute that calculates an annual salary based on a
monthly salary would be MONTHLY_SALARY * 12
,
the read format for an attribute that does the same thing would
be %P * 12
. The former
does not require a column in the database whereas the latter does.
Custom format strings can also be used for INSERT and UPDATE
operations. For example, if you want to store an employees salary
in monthly terms rather than in annual terms, you would set the
write format to be %V /12
.
So, whenever the salary attribute is written back to the database,
its value is divided by 12.
Read format strings use %P as the substitution character
for the value that is being formatted whereas write format strings
use %V as the substitution character. If, for example, you
are deriving an annual salary from a column that stores salaries
in monthly terms (MONTHLY_SALARY
),
the format string is %P * 12
.
So rather than sending the database server a message of SELECT
MONTHY_SALARY
, it is instead sent SELECT
MONTHY_SALARY * 12
.
You can use any legal SQL value expression in a format string and you can even use database-specific features such as functions. (A common case function is one that converts data from one type to another when it is read or written, such as converting a string to a date when writing and from a date to a string when reading). Using database-specific features affords the application more flexibility but limits its portability. You are responsible for ensuring that the SQL is well-formed and can be understood by the database server.
Using custom read and write formats is probably useful only when dealing with legacy data in which the stored data is out of sync with your current business logic. In the examples used above, the old business logic would be to store salaries based on monthly terms. The great database application youre writing uses this legacy data store but displays salaries in annual terms. To maintain the integrity of the data in the database, its important to divide annual salary by twelve upon each commit. This transformation, however, should be transparent to the end user, so using custom read and write formats solves this problem.