/[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.4 - (show annotations)
Sat Mar 1 20:17:57 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +5 -1 lines
FILE REMOVED
renamed to AbstractDataSource.inc

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

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