/[cvs]/nfo/php/libs/com.newsblob.phphtmllib/widgets/data_source/ProxyDataSource.inc
ViewVC logotype

Contents of /nfo/php/libs/com.newsblob.phphtmllib/widgets/data_source/ProxyDataSource.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Sat Mar 1 15:36:11 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.2: +122 -57 lines
+ debugging
+ renamed some methods regarding new proposal (build_proxy_options, fetch_result, etc.)

1 <?php
2 /**
3 * This file contains the ProxyDataSource child class
4 * that uses the Data::Driver::Proxy object to talk
5 * to a remote rpc server.
6 *
7 * @author Andreas Motl <andreas.motl@ilo.de>
8 * @package phpHtmlLib
9 * @module ProxyDataSource
10 *
11 */
12
13 /**
14 * $Id: ProxyDataSource.inc,v 1.2 2003/03/01 04:50:27 joko Exp $
15 *
16 * $Log: ProxyDataSource.inc,v $
17 * Revision 1.2 2003/03/01 04:50:27 joko
18 * encapsulated all output into tracing mode
19 * disabled tracing
20 *
21 * Revision 1.1 2003/03/01 03:10:40 joko
22 * + initial commit
23 *
24 *
25 */
26
27 /**
28 * This requires the MemoryDataSource base class
29 *
30 */
31 // V1: compile-time-include, stable since years ;-)
32 include_once($phphtmllib."/widgets/data_source/MemoryDataSource.inc");
33 // V2: runtime-load proposal, more flexible
34 // loadModule('MemoryDataSource', 'inc'); // doesn't work (would do if basepath of module is in libpath)
35 // loadModule($phphtmllib . '::widgets::data_source::MemoryDataSource', 'inc'); // works (by accident)
36 // loadModule($phphtmllib . "/widgets/data_source/MemoryDataSource", "inc"); // works (should be stable)
37 // loadModule($phphtmllib . "/widgets/data_source/MemoryDataSource.inc", null); // works (should be stable)
38
39
40
41 /**
42 * Have to have PEAR and DB included
43 * the pear dir must be in the
44 * include path.
45 */
46 // require_once("PEAR.php"); // FIXME: what about PEAR::XML::RPC?
47 // require_once("DB.php");
48
49 /**
50 * This ProxyDataSource child class is *completely* independent
51 * of a specific storage implementation and intended to be a wrapper
52 * class on the way from phpHtmlLib to Xyz.
53 * ("Yyz" gets represented by Data::Storage by now.....)
54 *
55 * ProxyDataSource interacts with an intermediate "proxy" object
56 * (e.g. Data::Driver::Proxy) when doing queries.
57 * Don't mix this up with a persistent database handle which gets
58 * reused each and every time for different queries.
59 * Here *is* a new instance of Data::Driver::Proxy for *each* query.
60 *
61 * But the point is: Caching! The actual *data* isn't read redundant!
62 *
63 *
64 * !!!!!! refactor this to Data::Driver::Proxy !!!!!! <-----------------
65 *
66 * Data::Driver::Proxy instantiates "handlers" below itself
67 * which act as encapsulated workers to actually do the stuff to do.
68 * It can cache data for "disconnected mode" using the
69 * php PEAR DB abstraction objects.
70 * One worker already implemented is Data::Driver::RPC::Remote, which
71 * talks to a RPC::XML server (todo: talk SOAP!) using PEAR::XML::RPC.
72 *
73 * --- refactored here, but: redundant somehow ---
74 * Data::Driver::Proxy uses a PEAR XML::RPC object to actually
75 * talk HTTP and serialize data chunks to and from XML,
76 * but adds some caching to this "process of fetching data from a remote side".
77 * It "proxies" arbitrary data chunks a) inside a native php4 session,
78 * b) by talking to a rdbms (single proxy-table) or c) [TODO] using PEAR::Cache.
79 * --- refactored here, but: redundant somehow ---
80 *
81 * !!!!!! refactor this to Data::Driver::Proxy !!!!!! <-----------------
82 *
83 *
84 * How to use?
85 *
86 * Pass an array holding "locator metadata" to the constructor.
87 * ProxyDataSource takes care of the rest.
88 *
89 * Pass an array to the constructor: (e.g.)
90 *
91 * 1. doing rpc-calls....
92 * $locator = array(
93 * type => 'rpc',
94 * metadata => array( Host => 'localhost', Port => '8765' ),
95 * );
96 * $source = new ProxyDataSource($locator);
97 * $this->set_data_source( &$source );
98 *
99 * 2. [proposal] common datahandles....
100 * $locator = array(
101 * type => 'mysql',
102 * dsn => 'known dsn markup',
103 * );
104 * $source = new ProxyDataSource($locator);
105 * $this->set_data_source( &$source );
106 *
107 * @author Andreas Motl <andreas.motl@ilo.de>
108 * @author Sebastian Utz <seut@tunemedia.de>
109 * @copyright (c) 2003 - All Rights reserved.
110 * @license GNU LGPL (GNU Lesser General Public License)
111 *
112 * @author-url http://www.netfrag.org/~joko/
113 * @author-url http://www.netfrag.org/~jonen/
114 * @license-url http://www.gnu.org/licenses/lgpl.txt
115 *
116 * @package phpHtmlLib
117 * @module ProxyDataSource
118 *
119 */
120
121 /**
122 * Todo:
123 *
124 * o mungle this to be able to be wrapped around phpHtmlLib's own storage-handles
125 * o implement another Data::Driver::Proxy container
126 *
127 */
128
129
130 class ProxyDataSource extends MemoryDataSource {
131
132 /**
133 * This var holds the locator metadata hash
134 * that is used to feed metadata to a per-query-instance
135 * of a Data::Driver::Proxy object.
136 *
137 */
138 var $_locator = NULL;
139
140
141 /**
142 * This var holds the query hash
143 * that is used to feed as query to a per-query-instance
144 * of a Data::Driver::Proxy object.
145 *
146 */
147 var $_query = NULL;
148
149
150 /**
151 * This var holds the Proxy object
152 * that is used to do the work.
153 * It acts as a dispatcher combining result caching.
154 * It is assumed that this provides 4 methods:
155 * queryData() - execute a query against a data storage
156 * querySchema() - execute a query against underlying storage metadata
157 * sendCommand() - send a command against an arbitrary execution engine
158 *
159 */
160 var $_proxy = NULL;
161
162
163 /**
164 * This var holds options fed to the Proxy object
165 * These are built from locator metadata (_locator) and query arguments (_query)
166 * It's a simple structured hash:
167 * $proxy_options = array(
168 * method => '<remote-method-name>',
169 * args => array('list', 'of', 'arguments')
170 * );
171 *
172 */
173 var $_proxy_options = NULL;
174
175
176 /**
177 * this holds the query result from the
178 * Data::Driver::Proxy->queryXyz() call
179 *
180 */
181 var $_result = NULL;
182
183 /**
184 * This holds some information about the tracing level.
185 *
186 */
187 var $_debug = array(
188 notice => 0,
189 trace => 0,
190 payload => 0,
191 );
192
193
194 /**
195 * The constructor is used to pass in the
196 * locator metadata hash.
197 *
198 * @param LocatorMetadataHash array - layout: array( type => '', metadata => '', dsn => '' )
199 * @param Query array - layout: array( type => '', metadata => '', dsn => '' )
200 */
201 function ProxyDataSource( &$locator, $query ) {
202
203 $this->set_locator( $locator );
204 $this->set_query( $query );
205 }
206
207 /**
208 * Set the locator metadata hash we will feed *partly*
209 * to an encapsulated Data::Driver::Proxy instance.
210 *
211 * @param LocatorMetadataHash array -
212 *
213 */
214 function set_locator( &$locator ) {
215 $this->_locator = &$locator;
216 }
217
218 /**
219 * Set the query metadata hash we will feed *completely*
220 * to an encapsulated Data::Driver::Proxy instance.
221 *
222 * @param QueryDeclaration array -
223 *
224 */
225 function set_query( $query ) {
226 $this->_query = $query;
227 }
228
229 /**
230 * Directly inject a Data::Driver::Proxy instance to use.
231 *
232 * @param Data::Driver::Proxy object - &$proxy
233 *
234 */
235 function set_proxy( &$proxy ) {
236 $this->_proxy = &$proxy;
237 }
238
239 /**
240 * Issue remote/proxy call
241 * Stolen from Application_AbstractBackend::_remote_method (RefactoringProposal?)
242 * Tweaked a bit: proxy package now taken from $this->_proxy_name
243 *
244 * Create a new instance of a proxy and store it for later reuse.
245 * Read the locator metadata hash and create
246 * the proxy handler instance using passed-in name.
247 *
248 * @param string - $proxy_name (namespaced classname - perl syntax - e.g.: Data::Driver::Proxy)
249 *
250 */
251 function do_proxy_call() {
252
253
254 // 1. read args
255
256 $arg_list = func_get_args();
257 $command = array_shift($arg_list);
258 $cache_key = join("-", array(session_id(), $command, join('_', $arg_list) ));
259 //print "cache_key: $cache_key<br>";
260
261 // FIXME: what if arg_list still contains more elements after doing this?
262 $query = array_shift($arg_list);
263
264
265 // 2. prepare proxy-options
266
267 // read from locator metadata
268 $proxy_name = $this->_locator[metadata][package];
269 $rpcinfo = array( Host => $this->_locator[metadata][Host], Port => $this->_locator[metadata][Port] );
270
271 // FIXME! implement this into Data::Driver::RPC::Remote!
272 //$rpcinfo[to_latin] = 1;
273
274 // FIXME! patch query
275 if (sizeof($query) == 1) {
276 $query = $query[0];
277 }
278
279 // -------------------- clone this & modify ----------
280 $proxy = mkObject($proxy_name, $cache_key, array( key => 1, command => $command, query => $query, remote => 1, rpcinfo => $rpcinfo, cache => array( db => 0, session => 1 ) ) );
281 $this->set_proxy( $proxy );
282 //$result = $resultHandle->getAttributes();
283 //return $result;
284 //$this->_result = $resultHandle->getAttributes();
285 //$this->_result = $this->_proxy->getAttributes();
286 // -------------------- clone this & modify ----------
287
288 }
289
290 function O_do_query() {
291 $this->_result = $this->_db->query($this->_query);
292 if (DB::isError($this->_result)) {
293 $msg = $this->_result->getMessage();
294 user_error("PEARSQLDataListSource::do_query() - query failed : ".$msg);
295 }
296 }
297
298 function build_proxy_options() {
299
300 // make up a command from metadata
301 // FIXME: abstract this some more (e.g. via a CommandMapper|Registry)
302 switch ($this->_query[metatype]) {
303 case 'data':
304 //$command = 'queryData';
305 $command = 'getObjects'; // FIXME!!!
306 $args = array();
307 switch ($this->_query[vartype]) {
308 case 'object':
309 if (!$this->_query[classname]) {
310 $msg = "_query[vartype] == 'object' requires _query[classname]";
311 user_error("ProxyDataSource::do_query() - failed: " . $msg);
312 }
313 array_push($args, $this->_query[classname]);
314 break;
315 }
316 break;
317 case 'schema':
318 $command = 'querySchema';
319 break;
320 }
321
322 // trace
323 $this->debug(null, '<b>= = = = = = = = = = = = = = = = = = = = = =</b>');
324 $this->trace('build_proxy_options', array(
325 "_locator" => $this->_locator,
326 "_query" => $this->_query,
327 "command" => '<b>' . $command . "</b>",
328 "args" => $args
329 ));
330
331 $this->_proxy_options = array(
332 method => $command,
333 args => $args,
334 );
335
336 }
337
338 function fetch_result() {
339
340 $this->build_proxy_options();
341 $method = $this->_proxy_options[method];
342 $args = $this->_proxy_options[args];
343
344 // pre-flight checks
345 if (!$method) {
346 $msg = "Remote command could not be resolved, please pass in or check configuration.";
347 user_error("ProxyDataSource::do_query() - failed: " . $msg);
348 return;
349 }
350
351 // do remote call here and get result
352 // FIXME: handle synchronous/asynchronous mode here!!!
353 $this->do_proxy_call($method, $args);
354 // TODO: ... = $this->poll_proxy_result and $this->get_proxy_result
355 $this->_result = $this->_proxy->getAttributes();
356
357 // trace
358 if ($this->_debug[notice]) {
359 //print "_result = " . Dumper($this->_result);
360 print "_result - count = " . sizeof($this->_result) . "<br/>";
361 }
362
363 }
364
365
366 function do_query() {
367 //print "query!<br/>";
368 $this->fetch_result();
369 $this->handle_result();
370 }
371
372 function get_header() {
373 $this->fetch_result();
374 $this->read_labels_from_result();
375 return $this->get_labels();
376 }
377
378
379 function O_do_prequery() {
380 //print "prequery!<br/>";
381 // HACK!!!
382 // modify behaviour here: for now it is needed to call for the schem
383 // eventually modify here to get schema from some registry component (already locally available)
384 $this->fetch_result();
385 //print Dumper($this->_result);
386 //print Dumper($this->_result[0]);
387 //exit;
388
389 //$this->_get_header();
390 }
391
392
393 function O_get_header() {
394 //$this->do_prequery();
395 // FIXME: prevent multi-calls by base class
396 $this->fetch_result();
397 foreach($this->_result[0] as $key => $value) {
398 array_push($this->_data_keys, $key);
399 }
400
401 $this->set_schema($this->_result[0]);
402
403 //$this->_get_header();
404 //return $this->_data_keys;
405
406 }
407
408
409
410
411
412
413
414
415
416
417 /**
418 * This function gets the next data row
419 * from the query()
420 *
421 * @return array()
422 */
423 function O_get_next_data_row() {
424 return $this->_result->fetchRow(DB_FETCHMODE_ASSOC);
425 }
426
427 /**
428 * This function builds the limit
429 * clause portion of a DB query.
430 *
431 * @return string - the limit portion of
432 * the query.
433 */
434 function O_build_limit_clause($offset, $limit) {
435 if ($this->get_limit() != -1 ) {
436 if ($offset == '' || $offset == "none") {
437 $offset = 0;
438 }
439 switch(get_class($this->_db)) {
440 case "db_mysql":
441 $clause = " LIMIT $offset, $limit ";
442 break;
443 case "db_pgsql":
444 $clause = " LIMIT $limit, $offset ";
445 break;
446 default:
447 $clause = " LIMIT $offset, $limit ";
448 break;
449 }
450 return $clause;
451 } else {
452 return NULL;
453 }
454 }
455
456 /**
457 * find the number of rows to be returned
458 * from a query from a table and where clause
459 *
460 * @param string $table - the table to count from
461 * @param string $where_clause - a where clause
462 *
463 * @return int the # of rows
464 */
465 function O_count($tables, $where_clause='', $count_clause='*') {
466 $query = "select count(".$count_clause.") as COUNT from ".$tables." ".$where_clause;
467 $result = $this->_db->query($query);
468 if (DB::isError($this->_result)) {
469 $msg = $result->getMessage();
470 user_error("PEARSQLDataListSource::count() - query failed : ".$msg);
471 }
472 $value = $result->fetchRow(DB_FETCHMODE_ASSOC);
473 return ($value ? (int)$value["COUNT"] : NULL);
474 }
475
476 }
477
478 ?>

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