NAME
PApp::DataRef - reference data stored in scalars, databases...
SYNOPSIS
use
PApp::DataRef;
DESCRIPTION
You often want to store return values from HTML forms (e.g. "editform" in macro) or other "action at a distance" events in your state variable or in a database (e.g. after updates). The DBIx::Recordset provides similar functionality.
PApp::DataRef
provides the means to create "handles" that can act like normal perl references. When accessed they fetch/store data from the underlying storage.
All of the generated references and handles can be serialized.
- $hd = new PApp::DataRef 'DB_row', table => $table, where => [key, value], ...
-
Create a new handle to a table in a SQL database.
table
is the name (view) of the database table. The handle will act like a reference to a hash. Accessing the hash returns references to tied scalars that can be read or set (or serialized).my
$hd
= new PApp::DataRef
'DB_row'
,
table
=> env,
where
=> [
name
=>
'TT_LIBDIR'
];
print
${
$hd
->{value} },
"\n"
;
${
$hd
->{value} } =
"new libdir value"
;
The default database handle (
$PApp::SQL::DBH
) is used for all sql accesses. (Future versions might be more intelligent).As a special case, if the
value
part of thewhere
agruments is undef, it will be replaced by some valid (newly created) id on the first STORE operation. This currently only works for mysql.Parameters
table the database table to
use
.
key a string or arrayref containing the (primary) key fields.
id a
scalar
or araryref giving the
values
for
the key.
where [deprecated but supported] a array-
ref
with
the primary key
fieldname and primary key value.
autocommit
if
set to one (
default
) automatically store the contents
when
necessary or
when
the object gets destroyed.
delay
if
set,
do
not
write
the table
for
each
update.
(delay implies caching of stored
values
(!))
cache
if
set, cache
values
that were
read
.
preload
if
set to a true value, preloads the
values
from the table on
object creation. If set to an array reference, only the mentioned
fields are being cached. Implies C<
cache
=> 1>.
database the PApp::SQL::Database object to
use
. If not specified,
the
default
database at the
time
of the new call is used.
insertid
when
set to true, makes this object allocate sequences using
sql_insertid.
to handle the case where
no
id is
given
, in which case this parameter
describes how to allocate a new id).
utf8 can be set to a boolean, an arrayref or hashref that decides
wether to force the utf8 bit on or off
for
the selected fields.
- $hd = new $dataref arg => value, ...
-
Instead of specifying all the same parameters again and again, you can create a partial DataRef object (e.g. one without an id) with default parameters and use this form of the method invocation to "specialise", e.g.
my
$template
= new PApp::DataRef
'DB_row'
,
table
=>
"message"
,
key
=>
"id"
;
for
(1,2,3) {
my
$row
=
$template
->new(
id
=>
$_
);
...
}
- $hd = new PApp::DataRef 'Scalar', fetch => ..., ...
-
Create a scalar reference that calls your callbacks when accessed. Valid arguments are:
fetch
=> coderef(
$self
)
# ref not present
fetch
=> coderef(
$self
,
$value
)
# ref present
A coderef which is to be called
for
every
read
access
value
=> constant
As an alternative to fetch, always
return
a constant on
read
accesses
ref
=>
scalar
-
ref
When present, this references the
scalar
that is passed to the fetch
method or overwritten by the store method.
store
=> coderef(
$value
,
$value
)
# ref not present (first argument is DEPRECATED)
store
=> coderef(
$self
,
$value
)
# ref present
A coderef which is to be called
with
the new value
for
every
write
access. If
ref
is
given
, the new value should be returned from this
callback. If the callback returns the empty list, the value won't be
changed.
For read access, either
fetch
,value
orref
must be present (they are checked in this order). Ifstore
is missing, stored values are thrown away. - $hd->{fieldname} or $hd->{[fieldname, extra-args]}
-
Return a lvalue to the given field of the row. The optional arguments
fetch
andstore
can be given code-references that are called at every fetch and store, and should return their first argument (possibly modified), e.g. to fetch and store a crypt'ed password field:my
$pass_fetch
= create_callback {
""
};
my
$pass_store
= create_callback {
crypt
$_
[1], <salt> };
$hd
->{[
"password"
,
fetch
=>
$pass_fetch
,
store
=>
$pass_store
]};
Additional named parameters are:
fetch
=>
$fetch_cb
,
store
=>
$store_cb
,
Functions that should be called
with
the fetched/to-be-stored value
as second argument that should be returned, probably
after
some
transformations have been used on it. This can be used to convert
sql-sets or password fields from/to their internal database
format
.
If the store function returns nothing (an empty
'list'
, as it is
called in list context), the update is being skipped.
L<PApp::Callback>
for
a way to create serializable code references.
PApp::DataRef::DB_row predefines some filter types (these functions
return
four elements, i.e.
fetch
=> xxx,
store
=> xxx, so that you
can just cut & paste them).
PApp::DataRef::DB_row::filter_sql_set
converts strings of the form a,b,c into array-refs and
vice versa.
PApp::DataRef::DB_row::filter_password
returns the empty string and
crypt
's the value
if
nonempty.
PApp::DataRef::DB_row::filter_sfreeze_cr
filters the data through Compress::LZF's sfreeze_cr and sthaw.
- @key = $hd->id
-
Returns the key value(s) for the selected row, creating it if necessary.
- $hd->flush
-
Flush all pending store operations. See HOW FLUSHES ARE IMPLEMENTED below to see how, well, flushes are implemented on the SQL-level.
- $hd->dirty
-
Return true when there are store operations that are delayed. Call
flush
to execute these. - $hd->invalidate
-
Empties any internal caches. The next access will reload the values from the database again. Any dirty values will be discarded.
- $hd->discard
-
Discard all pending store operations. Only sensible when
delay
is true. - $hd->delete
-
Delete the row from the database
How Flushes are Implemented
When a single value (delay => 0) is being read or written, DataRef creates a single access:
SELECT column FROM table WHERE id = ?
UPDATE table SET column = ? where id = ?
In other cases, DataRef reads and writes full rows:
SELECT * FROM table WHERE id = ?
When a row is being written and the id is undef
or zero, DataRef uses the insertid
callback to create a new insertion id followed by an INSERT (if insretid is 1, it uses an INSERT followed by sql_insertid
, so your id volumn should better be defined as auto increment in your database). If the id is defined, the update is driver specific:
for mysql (if appropriate):
REPLACE INTO table (...) VALUES (...)
and for other databases:
INSERT INTO table (...) VALUES (...)
and,
if
the above commend fails,
UPDATE table SET ? = ?, ? = ?, ... WHERE id = ?
no checking wether the UPDATE succeeded is done (yet).
SEE ALSO
PApp.
AUTHOR
Marc Lehmann <schmorp
@schmorp
.de>