/[cvs]/nfo/php/libs/net.php.pear/DB/storage.php
ViewVC logotype

Annotation of /nfo/php/libs/net.php.pear/DB/storage.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Oct 29 19:11:41 2002 UTC (21 years, 8 months ago) by cvsjoko
Branch: MAIN
CVS Tags: HEAD
+ new pear-libraries

1 cvsjoko 1.1 <?php
2     //
3     // +----------------------------------------------------------------------+
4     // | PHP Version 4 |
5     // +----------------------------------------------------------------------+
6     // | Copyright (c) 1997-2002 The PHP Group |
7     // +----------------------------------------------------------------------+
8     // | This source file is subject to version 2.02 of the PHP license, |
9     // | that is bundled with this package in the file LICENSE, and is |
10     // | available at through the world-wide-web at |
11     // | http://www.php.net/license/2_02.txt. |
12     // | If you did not receive a copy of the PHP license and are unable to |
13     // | obtain it through the world-wide-web, please send a note to |
14     // | license@php.net so we can mail you a copy immediately. |
15     // +----------------------------------------------------------------------+
16     // | Author: Stig Bakken <stig@php.net> |
17     // +----------------------------------------------------------------------+
18     //
19     // $Id: storage.php,v 1.28 2002/02/28 08:27:11 sebastian Exp $
20     //
21     // DB_storage: a class that lets you return SQL data as objects that
22     // can be manipulated and that updates the database accordingly.
23     //
24    
25     require_once "PEAR.php";
26     require_once "DB.php";
27    
28     /**
29     * DB_storage provides an object interface to a table row. It lets
30     * you add, delete and change rows without using SQL.
31     *
32     * @author Stig Bakken <stig@php.net>
33     *
34     * @package DB
35     */
36     class DB_storage extends PEAR
37     {
38     /** the name of the table (or view, if the backend database supports
39     updates in views) we hold data from */
40     var $_table = null;
41    
42     /** which column(s) in the table contains primary keys, can be a
43     string for single-column primary keys, or an array of strings
44     for multiple-column primary keys */
45     var $_keycolumn = null;
46    
47     /** DB connection handle used for all transactions */
48     var $_dbh = null;
49    
50     /** an assoc with the names of database fields stored as properties
51     in this object */
52     var $_properties = array();
53    
54     /** an assoc with the names of the properties in this object that
55     have been changed since they were fetched from the database */
56     var $_changes = array();
57    
58     /** flag that decides if data in this object can be changed.
59     objects that don't have their table's key column in their
60     property lists will be flagged as read-only. */
61     var $_readonly = false;
62    
63     /** function or method that implements a validator for fields that
64     are set, this validator function returns true if the field is
65     valid, false if not */
66     var $_validator = null;
67    
68     /**
69     * Constructor
70     *
71     * @param $table string the name of the database table
72     *
73     * @param $keycolumn mixed string with name of key column, or array of
74     * strings if the table has a primary key of more than one column
75     *
76     * @param $dbh object database connection object
77     *
78     * @param $validator mixed function or method used to validate
79     * each new value, called with three parameters: the name of the
80     * field/column that is changing, a reference to the new value and
81     * a reference to this object
82     *
83     */
84     function DB_storage($table, $keycolumn, &$dbh, $validator = null)
85     {
86     $this->PEAR('DB_Error');
87     $this->_table = $table;
88     $this->_keycolumn = $keycolumn;
89     $this->_dbh = $dbh;
90     $this->_readonly = false;
91     $this->_validator = $validator;
92     }
93    
94     /**
95     * Utility method to build a "WHERE" clause to locate ourselves in
96     * the table.
97     *
98     * XXX future improvement: use rowids?
99     *
100     * @access private
101     */
102     function _makeWhere($keyval = null)
103     {
104     if (is_array($this->_keycolumn)) {
105     if ($keyval === null) {
106     for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
107     $keyval[] = $this->{$this->_keycolumn[$i]};
108     }
109     }
110     $whereclause = '';
111     for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
112     if ($i > 0) {
113     $whereclause .= ' AND ';
114     }
115     $whereclause .= $this->_keycolumn[$i];
116     if (is_null($keyval[$i])) {
117     // there's not much point in having a NULL key,
118     // but we support it anyway
119     $whereclause .= ' IS NULL';
120     } else {
121     $whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]);
122     }
123     }
124     } else {
125     if ($keyval === null) {
126     $keyval = @$this->{$this->_keycolumn};
127     }
128     $whereclause = $this->_keycolumn;
129     if (is_null($keyval)) {
130     // there's not much point in having a NULL key,
131     // but we support it anyway
132     $whereclause .= ' IS NULL';
133     } else {
134     $whereclause .= ' = ' . $this->_dbh->quote($keyval);
135     }
136     }
137     return $whereclause;
138     }
139    
140     /**
141     * Method used to initialize a DB_storage object from the
142     * configured table.
143     *
144     * @param $keyval mixed the key[s] of the row to fetch (string or array)
145     *
146     * @return int DB_OK on success, a DB error if not
147     */
148     function setup($keyval)
149     {
150     $qval = $this->_dbh->quote($keyval);
151     $whereclause = $this->_makeWhere($keyval);
152     $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
153     $sth = $this->_dbh->query($query);
154     if (DB::isError($sth)) {
155     return $sth;
156     }
157     $row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
158     if (DB::isError($row)) {
159     return $row;
160     }
161     if (empty($row)) {
162     return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null,
163     $query, null, true);
164     }
165     foreach ($row as $key => $value) {
166     $this->_properties[$key] = true;
167     $this->$key = $value;
168     }
169     return DB_OK;
170     }
171    
172     /**
173     * Create a new (empty) row in the configured table for this
174     * object.
175     */
176     function insert($newpk)
177     {
178     if (is_array($this->_keycolumn)) {
179     $primarykey = $this->_keycolumn;
180     } else {
181     $primarykey = array($this->_keycolumn);
182     }
183     settype($newpk, "array");
184     for ($i = 0; $i < sizeof($primarykey); $i++) {
185     $pkvals[] = $this->_dbh->quote($newpk[$i]);
186     }
187    
188     $sth = $this->_dbh->query("INSERT INTO $this->_table (" .
189     implode(",", $primarykey) . ") VALUES(" .
190     implode(",", $pkvals) . ")");
191     if (DB::isError($sth)) {
192     return $sth;
193     }
194     if (sizeof($newpk) == 1) {
195     $newpk = $newpk[0];
196     }
197     $this->setup($newpk);
198     }
199    
200     /**
201     * Output a simple description of this DB_storage object.
202     * @return string object description
203     */
204     function toString()
205     {
206     $info = get_class($this);
207     $info .= " (table=";
208     $info .= $this->_table;
209     $info .= ", keycolumn=";
210     if (is_array($this->_keycolumn)) {
211     $info .= "(" . implode(",", $this->_keycolumn) . ")";
212     } else {
213     $info .= $this->_keycolumn;
214     }
215     $info .= ", dbh=";
216     if (is_object($this->_dbh)) {
217     $info .= $this->_dbh->toString();
218     } else {
219     $info .= "null";
220     }
221     $info .= ")";
222     if (sizeof($this->_properties)) {
223     $info .= " [loaded, key=";
224     $keyname = $this->_keycolumn;
225     if (is_array($keyname)) {
226     $info .= "(";
227     for ($i = 0; $i < sizeof($keyname); $i++) {
228     if ($i > 0) {
229     $info .= ",";
230     }
231     $info .= $this->$keyname[$i];
232     }
233     $info .= ")";
234     } else {
235     $info .= $this->$keyname;
236     }
237     $info .= "]";
238     }
239     if (sizeof($this->_changes)) {
240     $info .= " [modified]";
241     }
242     return $info;
243     }
244    
245     /**
246     * Dump the contents of this object to "standard output".
247     */
248     function dump()
249     {
250     reset($this->_properties);
251     while (list($prop, $foo) = each($this->_properties)) {
252     print "$prop = ";
253     print htmlentities($this->$prop);
254     print "<BR>\n";
255     }
256     }
257    
258     /**
259     * Static method used to create new DB storage objects.
260     * @param $data assoc. array where the keys are the names
261     * of properties/columns
262     * @return object a new instance of DB_storage or a subclass of it
263     */
264     function &create($table, &$data)
265     {
266     $classname = get_class($this);
267     $obj = new $classname($table);
268     reset($data);
269     while (list($name, $value) = each($data)) {
270     $obj->_properties[$name] = true;
271     $obj->$name = &$value;
272     }
273     return $obj;
274     }
275    
276     /**
277     * Loads data into this object from the given query. If this
278     * object already contains table data, changes will be saved and
279     * the object re-initialized first.
280     *
281     * @param $query SQL query
282     *
283     * @param $params parameter list in case you want to use
284     * prepare/execute mode
285     *
286     * @return int DB_OK on success, DB_WARNING_READ_ONLY if the
287     * returned object is read-only (because the object's specified
288     * key column was not found among the columns returned by $query),
289     * or another DB error code in case of errors.
290     */
291     // XXX commented out for now
292     /*
293     function loadFromQuery($query, $params = null)
294     {
295     if (sizeof($this->_properties)) {
296     if (sizeof($this->_changes)) {
297     $this->store();
298     $this->_changes = array();
299     }
300     $this->_properties = array();
301     }
302     $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
303     if (DB::isError($rowdata)) {
304     return $rowdata;
305     }
306     reset($rowdata);
307     $found_keycolumn = false;
308     while (list($key, $value) = each($rowdata)) {
309     if ($key == $this->_keycolumn) {
310     $found_keycolumn = true;
311     }
312     $this->_properties[$key] = true;
313     $this->$key = &$value;
314     unset($value); // have to unset, or all properties will
315     // refer to the same value
316     }
317     if (!$found_keycolumn) {
318     $this->_readonly = true;
319     return DB_WARNING_READ_ONLY;
320     }
321     return DB_OK;
322     }
323     */
324    
325     /**
326     * Modify an attriute value.
327     */
328     function set($property, $newvalue)
329     {
330     // only change if $property is known and object is not
331     // read-only
332     if ($this->_readonly) {
333     return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
334     null, null, null, true);
335     }
336     if (@isset($this->_properties[$property])) {
337     if (empty($this->_validator)) {
338     $valid = true;
339     } else {
340     $valid = @call_user_func($this->_validator,
341     $this->_table,
342     $property,
343     $newvalue,
344     $this->$property,
345     $this);
346     }
347     if ($valid) {
348     $this->$property = $newvalue;
349     @$this->_changes[$property]++;
350     } else {
351     return $this->raiseError(null, DB_ERROR_INVALID, null,
352     null, "invalid field: $property",
353     null, true);
354     }
355     return true;
356     }
357     return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null,
358     null, "unknown field: $property",
359     null, true);
360     }
361    
362     /**
363     * Fetch an attribute value.
364     *
365     * @param string attribute name
366     *
367     * @return attribute contents, or null if the attribute name is
368     * unknown
369     */
370     function &get($property)
371     {
372     // only return if $property is known
373     if (isset($this->_properties[$property])) {
374     return $this->$property;
375     }
376     return null;
377     }
378    
379     /**
380     * Destructor, calls DB_storage::store() if there are changes
381     * that are to be kept.
382     */
383     function _DB_storage()
384     {
385     if (empty($this->_discard) && sizeof($this->_changes)) {
386     $this->store();
387     }
388     $this->_properties = array();
389     $this->_changes = array();
390     $this->_table = null;
391     }
392    
393     /**
394     * Stores changes to this object in the database.
395     *
396     * @return DB_OK or a DB error
397     */
398     function store()
399     {
400     while (list($name, $changed) = each($this->_changes)) {
401     $params[] = &$this->$name;
402     $vars[] = $name . ' = ?';
403     }
404     if ($vars) {
405     $query = 'UPDATE ' . $this->_table . ' SET ' .
406     implode(', ', $vars) . ' WHERE ' .
407     $this->_makeWhere();
408     $stmt = $this->_dbh->prepare($query);
409     $res = $this->_dbh->execute($stmt, $params);
410     if (DB::isError($res)) {
411     return $res;
412     }
413     $this->_changes = array();
414     }
415     return DB_OK;
416     }
417    
418     /**
419     * Remove the row represented by this object from the database.
420     *
421     * @return mixed DB_OK or a DB error
422     */
423     function remove()
424     {
425     if ($this->_readonly) {
426     return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
427     null, null, null, true);
428     }
429     $query = 'DELETE FROM ' . $this->_table .' WHERE '.
430     $this->_makeWhere();
431     $res = $this->_dbh->query($query);
432     if (DB::isError($res)) {
433     return $res;
434     }
435     foreach ($this->_properties as $prop => $foo) {
436     unset($this->$prop);
437     }
438     $this->_properties = array();
439     $this->_changes = array();
440     return DB_OK;
441     }
442     }
443    
444     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed