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