/[cvs]/nfo/php/libs/org.netfrag.glib/DataSource/Generic.php
ViewVC logotype

Contents of /nfo/php/libs/org.netfrag.glib/DataSource/Generic.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.29 - (show annotations)
Thu Aug 11 14:05:42 2005 UTC (18 years, 11 months ago) by jonen
Branch: MAIN
CVS Tags: HEAD
Changes since 1.28: +5 -1 lines
+ added arguments to query

1 <?php
2 /**
3 * This file contains the GenericDataSource child class
4 *
5 * @author Andreas Motl <andreas.motl@ilo.de>
6 * @package org.netfrag.glib
7 * @name DataSource::Generic
8 *
9 */
10
11 /**
12 * Cvs-Log:
13 *
14 * $Id: Generic.php,v 1.28 2004/10/07 14:11:28 jonen Exp $
15 *
16 * $Log: Generic.php,v $
17 * Revision 1.28 2004/10/07 14:11:28 jonen
18 * + added HACK related to DataList-filters which are mapped to backend now (page-control!)
19 *
20 * Revision 1.27 2004/06/15 12:50:48 joko
21 * disabled caching in "datasource_handler_call"
22 *
23 * Revision 1.26 2003/12/14 01:53:42 jonen
24 * implemented 'SELECT' mode for selecting existing object-refereneces as child-nodes
25 *
26 * Revision 1.25 2003/11/17 18:01:03 jonen
27 * bugfix: php cannot use perl-syntax!! ;-)
28 *
29 * Revision 1.23 2003/07/14 10:02:32 jonen
30 * removed debug dumper
31 *
32 * Revision 1.22 2003/06/06 04:25:45 joko
33 * fix: query args get encapsulated once more
34 *
35 * Revision 1.21 2003/05/10 18:14:50 jonen
36 * + implements 'create' of item (query mapping part)
37 *
38 * Revision 1.20 2003/04/19 16:07:15 jonen
39 * + added '_query[list_meta]' at 'queryData' needed for meta query args
40 * (e.g. at UserManagment)
41 *
42 * Revision 1.19 2003/04/18 15:40:51 joko
43 * NEW: tree data handling
44 * introduced new adapter: DataSource::Adapter::Free
45 * enhanced datasource_handler_buildoptions: now handles a) case 'tree' b) _query[filter]
46 *
47 * Revision 1.18 2003/04/11 00:55:49 joko
48 * updated 'datasource_handler_buildoptions': action dispatcher now aware of 'delete'
49 *
50 * Revision 1.17 2003/04/09 02:07:33 joko
51 * CHANGE: renamed key 'classname' through 'nodename'
52 *
53 * Revision 1.16 2003/04/08 17:55:20 joko
54 * CHANGE: renamed property 'datasource' to 'transport'
55 * NEW: new case 'method' in 'function datasource_handler_buildoptions'
56 * minor fixes: updated logging/debugging messages
57 *
58 * Revision 1.15 2003/04/06 04:46:33 joko
59 * renamed linking function
60 * mozilla fixes
61 *
62 * Revision 1.14 2003/04/04 21:19:21 joko
63 * modified exception handling (enhanced, purged redundant code)
64 *
65 * Revision 1.13 2003/04/04 02:37:14 jonen
66 * _query[action] == write
67 *
68 * Revision 1.12 2003/03/29 08:00:48 joko
69 * modified ErrorBoxing
70 *
71 * Revision 1.11 2003/03/28 06:45:26 joko
72 * VERBOSE mode
73 *
74 * Revision 1.10 2003/03/28 03:01:02 joko
75 * more fancy debugging-output
76 *
77 * Revision 1.9 2003/03/27 16:24:26 jonen
78 * + mugled namespace
79 * + added enhanced 'queryData'
80 *
81 * Revision 1.8 2003/03/20 07:22:14 jonen
82 * + modified case 'object' to 'objects'
83 * (cause its loads all *objects* of a given classname)
84 *
85 * Revision 1.7 2003/03/11 01:43:00 joko
86 * + fixed metadata for phpDocumentor
87 *
88 * Revision 1.6 2003/03/11 01:22:25 joko
89 * + fixed metadata for phpDocumentor
90 *
91 * Revision 1.5 2003/03/11 00:12:49 joko
92 * + fixed metadata for phpDocumentor
93 *
94 * Revision 1.4 2003/03/10 23:25:03 joko
95 * + fixed metadata for phpDocumentor
96 *
97 * Revision 1.3 2003/03/09 15:50:36 joko
98 * + additional metadata for Autodia
99 *
100 * Revision 1.2 2003/03/05 17:28:43 joko
101 * updated docu (phpDocumentor testing....)
102 *
103 * Revision 1.1 2003/03/05 12:04:00 joko
104 * + initial commit, from GenericDataSource
105 *
106 * Revision 1.3 2003/03/03 21:24:18 joko
107 * now based on DesignPattern::RemoteProxy
108 *
109 * Revision 1.2 2003/03/02 01:05:13 joko
110 * - purged old code
111 *
112 * Revision 1.1 2003/03/01 21:47:15 joko
113 * renamed from AbstractDataSource.inc
114 *
115 * Revision 1.1 2003/03/01 20:17:15 joko
116 * renamed from GenericDataSource.inc
117 * replaced '_proxy' through '_handler' to better associate the ability to act as a generic dispatcher handler
118 *
119 * Revision 1.3 2003/03/01 15:36:11 joko
120 * + debugging
121 * + renamed some methods regarding new proposal (build_handler_options, fetch_result, etc.)
122 *
123 * Revision 1.2 2003/03/01 04:50:27 joko
124 * encapsulated all output into tracing mode
125 * disabled tracing
126 *
127 * Revision 1.1 2003/03/01 03:10:40 joko
128 * + initial commit
129 *
130 */
131
132 /**
133 * This requires the MemoryDataSource base class
134 *
135 */
136
137 // V1: compile-time-include, stable since years ;-)
138 //include_once($phphtmllib."/widgets/data_source/MemoryDataSource.inc");
139
140 // V2: runtime-load proposal, more flexible
141 // loadModule('MemoryDataSource', 'inc'); // doesn't work (would do if basepath of module is in libpath)
142 // loadModule($phphtmllib . '::widgets::data_source::MemoryDataSource', 'inc'); // works (by accident)
143 // loadModule($phphtmllib . "/widgets/data_source/MemoryDataSource", "inc"); // works (should be stable)
144 // loadModule($phphtmllib . "/widgets/data_source/MemoryDataSource.inc", null); // works (should be stable)
145
146
147
148 /**
149 * Have to have PEAR and DB included
150 * the pear dir must be in the
151 * include path.
152 */
153 // require_once("PEAR.php"); // FIXME: what about PEAR::XML::RPC?
154 // require_once("DB.php");
155
156
157 loadModule('DesignPattern::Proxy');
158 loadModule('DesignPattern::TransparentProxy');
159 loadModule('DesignPattern::RemoteProxy');
160
161 //class GenericDataSource extends MemoryDataSource {
162 //class GenericDataSource extends DesignPattern_Proxy {
163 //class GenericDataSource extends DesignPattern_RemoteProxy {
164 //class GenericDataSource extends DesignPattern_TransparentProxy {
165
166 //class GenericDataSource extends MemoryDataSource {
167 //loadModule("DataSource::Proxy::Memory");
168 //class GenericDataSource extends DataSource_Proxy_Memory {
169 //class DataSource_GenericDataSource extends DataSource_Proxy_Memory {
170 //class DataSource_GenericDataSource extends DesignPattern_Proxy {
171 //class DataSource_GenericDataSource extends DataSource_Proxy_Memory {
172
173 // now independent!!! new class-inheritance-tree possible now!
174 // solved by having an Adapter *and* a Proxy here!
175 //class GenericDataSource {
176
177 loadModule('DesignPattern::AdapterProxy');
178
179
180
181 /**
182 * This GenericDataSource child class is *completely* independent
183 * of a specific storage implementation and intended to be a wrapper
184 * class on the way from phpHtmlLib to Xyz. <br>
185 * ("Yyz" gets represented by Data::Storage by now.....)
186 *
187 * GenericDataSource interacts with an intermediate "proxy" object
188 * (e.g. Data::Driver::Proxy) when doing queries. <br>
189 * <pre>
190 * Don't mix this up with a persistent database handle which gets
191 * reused each and every time for different queries.
192 * Here *is* a new instance of Data::Driver::Proxy for *each* query.
193 * </pre>
194 *
195 * But the point is: Caching! The actual *data* isn't read redundant!
196 *
197 * <pre>
198 * --- snipped into here from above ---
199 * that may use arbitrary code modules as database handlers.
200 * It's aims are to get together:
201 * o phpHtmlLibs "source-handlers"
202 * o PEAR's database handlers
203 * o custom ones (e.g. Data::Driver::Proxy object, which talks to a remote rpc server)
204 * --- snipped into here from above ---
205 * </pre>
206 *
207 * <p>
208 * !!!!!! refactor this to Data::Driver::Proxy !!!!!! <-----------------
209 *
210 * Data::Driver::Proxy instantiates "handlers" below itself
211 * which act as encapsulated workers to actually do the stuff to do.
212 * It can cache data for "disconnected mode" using the
213 * php PEAR DB abstraction objects.
214 * One worker already implemented is Data::Driver::RPC::Remote, which
215 * talks to a RPC::XML server (todo: talk SOAP!) using PEAR::XML::RPC.
216 *
217 * <pre>
218 * --- refactored here, but: redundant somehow ---
219 * Data::Driver::Proxy uses a PEAR XML::RPC object to actually
220 * talk HTTP and serialize data chunks to and from XML,
221 * but adds some caching to this "process of fetching data from a remote side".
222 * It "proxies" arbitrary data chunks a) inside a native php4 session,
223 * b) by talking to a rdbms (single proxy-table) or c) [TODO] using PEAR::Cache.
224 * --- refactored here, but: redundant somehow ---
225 * </pre>
226 *
227 * !!!!!! refactor this to Data::Driver::Proxy !!!!!! <-----------------
228 * </p>
229 *
230 *
231 * <p>
232 * <b>How to use?</b>
233 *
234 * Pass an array holding "locator metadata" to the constructor.
235 * GenericDataSource takes care of the rest.
236 *
237 * <pre>
238 * Pass an array to the constructor: (e.g.)
239 *
240 * 1. doing rpc-calls....
241 * <code>
242 * $locator = array(
243 * type => 'rpc',
244 * metadata => array( Host => 'localhost', Port => '8765' ),
245 * );
246 * $source = ne w GenericDataSource($locator);
247 * $this->set_data_source( &$source );
248 * </code>
249 *
250 * 2. [proposal] common datahandles....
251 * <code>
252 * $locator = array(
253 * type => 'mysql',
254 * dsn => 'known dsn markup',
255 * );
256 * $source = ne w GenericDataSource($locator);
257 * $this->set_data_source( &$source );
258 * </code>
259 * </pre>
260 * </p>
261 *
262 *
263 * @link http://www.netfrag.org/~joko/
264 * @author Andreas Motl <andreas.motl@ilo.de>
265 *
266 * @link http://www.netfrag.org/~jonen/
267 * @author Sebastian Utz <seut@tunemedia.de>
268 *
269 * @copyright (c) 2003 - All Rights reserved.
270 *
271 * @link http://www.gnu.org/licenses/lgpl.txt
272 * @license GNU LGPL (GNU Lesser General Public License)
273 *
274 *
275 * @package org.netfrag.glib
276 * @subpackage DataSource
277 * @name DataSource::Generic
278 *
279 * @todo this:
280 * o mungle this to be able to be wrapped around phpHtmlLib's own storage-handles
281 * o implement another Data::Driver::Proxy container
282 *
283 * <pre>
284 * !!!!!!!! THIS IS THE PROBLEM !!!!!!!!
285 * !!!!!!!! here is it where we have to break inheritance again !!!!!!!!
286 *
287 * THE CONFLICT: Beeing in phpHtmlLib *and* DesignPattern::TransparentProxy
288 * inheritance trees at the same time, which is *not* possible at
289 * declare-time. We *do* need some runtime-infrastructure to solve this!
290 *
291 * TODO: move build- and check-locator stuff from ObjectList to this place!!!
292 *
293 * ABOUT:
294 * 1. otherwhere: WebApp - scope:
295 * x handles page vs. block vs. widget; dispatches MVC-View
296 * 2. here: DataSource - scope:
297 * x handles bridge to frameworks (e.g. phpHtmlLib) vs. actual data driver libs (PEAR, etc.))
298 * o clean implementation using a DesignPattern::AdapterProxy
299 * </pre>
300 *
301 *
302 */
303 class DataSource_Generic extends DesignPattern_AdapterProxy {
304
305 // !!!!!!!! here is it where we have to break inheritance again !!!!!!!!
306 // !!!!!!!! THIS IS THE PROBLEM !!!!!!!!
307
308
309
310 /**
311 * This var holds the locator metadata hash
312 * that is used to feed metadata to a per-query-instance
313 * of an Adapter object.
314 *
315 */
316 //var $_locator = NULL;
317
318 /**
319 * This var holds the locator metadata hash
320 * which is built from some predefined rules
321 * using metadata from $_options and some
322 * other presets.
323 *
324 * See '_buildLocator' which acts as a dispatcher
325 * depending on $_options[transport].
326 * (main dispatching level)
327 *
328 * The structure of a full blown locator looks like this:
329 *
330 * $locator = array(
331 * type => '<your type specifying the datasource-type>',
332 * metadata => array(
333 * ... your arbitrary deep metadata structure ...
334 * ),
335 * [dsn => '<your dsn markup>'],
336 * );
337 *
338 * Example 1 - data is inside a rdbms, using a dsn to connect to it:
339 * $locator = array(
340 * type => 'sql',
341 * dsn => 'mysql://username:password@localhost/database',
342 * );
343 *
344 * Example 2 - data is inside an odbms, reachable by doing remote procedure calls (rpc):
345 * $locator = array(
346 * type => 'rpc',
347 * metadata => array(
348 * package => 'Data::Driver::Proxy',
349 * Host => 'localhost',
350 * Port => '8765',
351 * )
352 * );
353 *
354 */
355 var $_locator = NULL;
356
357
358 /**
359 * This var holds the module information required to
360 * create instances of a Proxy and an Adapter.
361 * Information might get extracted from a
362 * DataSource::Locator instance.
363 *
364 * --- A skeleton:
365 *
366 * $this->_modules = array(
367 * _proxy => array( _id => '', _module => '', _options = array(), _instance => &$obj),
368 * _adapter => array( _id => '', _module => '', _options = array(), _instance => &$obj),
369 * );
370 *
371 *
372 * --- An example:
373 *
374 * $this->_modules = array(
375 * _proxy => array( _id => 'rpc', _module => 'DesignPattern::RemoteProxy', _instance => &$obj),
376 * _adapter => array( _id => 'phpHtmlLib', _module => 'DataSource::Adapter::phpHtmlLib::DataListSource', _instance => &$obj),
377 * );
378 *
379 *
380 */
381 //var $_modules = NULL;
382
383
384 /**
385 * This var holds the query hash
386 * that is used to feed as query to a per-query-instance
387 * of a Data::Driver::Proxy object.
388 *
389 */
390 var $_query = NULL;
391
392
393 /**
394 * this holds the query result from the
395 * Data::Driver::Proxy->queryXyz() call
396 *
397 */
398 var $_result = NULL;
399
400
401
402 /**
403 * The constructor is used to pass in the
404 * locator metadata hash.
405 *
406 * @param LocatorMetadataHash array - layout: array( type => '', metadata => '', dsn => '' )
407 * @param Query array - layout: array( type => '', metadata => '', dsn => '' )
408 */
409
410
411 function DataSource_Generic( &$locator, $query ) {
412
413 // copy parameter from query to locator
414 //$this->_locator->merge_to($this->_locator, array( datasource_type => $query[transport] ), '_');
415 //$this->_locator->_datasource_type = $query[transport];
416 //$locator[_datasource_type] = $query[transport];
417
418 /**
419 * <!-- Autodia -->
420 * can do: (this is metadata supplied for Autodia, don't delete!)
421 * $this->_locator = new DataSource_Locator()
422 *
423 */
424
425 // build master locator
426 $this->_locator = php::mkComponent('DataSource::Locator', $locator, array( datasource_type => $query[transport] ) );
427 //exit;
428 //$this->_locator = php::mkComponent('DataSource::Locator');
429
430 $this->_locator->check();
431
432 // trace
433 //print "locator-obj: " . Dumper($this->_locator);
434 //print "locator-data: " . Dumper($locator_data);
435 //exit;
436
437
438
439 /*
440 $this->_modules = array(
441 _proxy => array( _id => $locator->_datasource_type ),
442 _adapter => array( _id => $locator->_adapter_type ),
443 );
444 */
445
446 //$this->set_locator( $locator );
447 //print "query: " . Dumper($query) . "<br>";
448 $this->set_query( $query );
449
450
451
452 /*
453 // V1:
454 // pre-flight: establish and check locator metadata
455 $this->_buildLocator();
456 $this->_checkLocator();
457 */
458
459
460
461 // pre-flight: check locator metadata
462 //$locator->build();
463 if (!$this->_locator->check()) {
464 user_error("DataSource::Generic: locator-check failed." . "<br/>" . "Locator was: " . Dumper($this->_locator) );
465 //exit;
466 return;
467 }
468
469 //exit;
470
471
472 /**
473 * <!-- Autodia -->
474 * can do: (this is metadata supplied for Autodia, don't delete!)
475 * $proxy = new DesignPattern_RemoteProxy()
476 *
477 */
478
479
480 // --- Proxy selector/dispatcher ...
481
482 switch ($this->_locator->_datasource_type) {
483 case 'rpc':
484 //$locator_data = $this->_locator->get_metadata();
485 //$this->_modules[_proxy][_options] = array( locator => $this->_locator, query => $query );
486 //$this->_modules[_proxy][_module] = 'DataSource::Proxy::XMLRPC';
487
488 //$this->_modules[_proxy][_module] = 'DesignPattern::RemoteProxy';
489 //$this->_modules[_proxy][_options] = $locator_data;
490
491 //$this->set_component_name('DesignPattern::RemoteProxy');
492 //$this->set_component_options($locator_data);
493
494 $this->set_component_name('DesignPattern::RemoteProxy');
495
496 break;
497 default:
498 user_error("Site::GenericPage: no Proxy could be selected!");
499 break;
500 }
501
502
503
504 /*
505 // V1:
506 // make up dummy args by now
507 $args = array(
508 adapter => 'phpHtmlLib',
509 );
510 */
511
512 // V2: now propagated from caller!
513
514 //print Dumper(array( locator => $locator, query => $query ));
515 //exit;
516
517 //$this->create_adapter($this->module, $this->function, $this->arguments);
518 //$this->set_handler( $this->get_adapter() );
519
520
521 // --- Adapter selector/dispatcher ...
522 // ... resolves this._modules.adapter._id to this._modules.adapter._module
523
524 switch ($locator->_adapter_type) {
525
526 case 'phpHtmlLib':
527 //$adapter_arguments = $args[title];
528 $this->set_adapter_module('DataSource::Adapter::phpHtmlLib::DataSource');
529
530 // in order to let the Adapter communicate with the Proxy,
531 // instantiate a wrapper method in a third namespace via
532 // Exporter::export_symbol(from, to)
533 $this->set_adapter_options($this);
534 break;
535
536 // NEW [2003-04-17]: Freedom for the adapter!
537 // phpHtmlLib didn't have a tree widget, but PEAR does.
538 // So: Free us from the phpHtmlLib-adapter in this case.
539 case 'free':
540 $this->set_adapter_module('DataSource::Adapter::Free');
541 $this->set_adapter_options($this);
542 break;
543
544 default:
545 user_error("DataSource::Generic: no Adapter could be selected: \$locator->_adapter_type='$locator->_adapter_type'");
546 break;
547 }
548
549
550
551 // --- module instantiation - Proxy and Adapter
552
553 //user_error("handle proxy here!");
554 //$this->create_proxy();
555
556 //print Dumper($this);
557
558 //print "this: " . Dumper($this);
559
560 // V1:
561 /*
562 $proxy = php::mkComponent($this->_modules[_proxy][_module], $this->_modules[_proxy][_options]);
563 print "proxy: " . Dumper($proxy);
564 //exit;
565 */
566
567 // V2:
568 /*
569 $resultHandle = mkObject('DesignPattern::RemoteProxy', $cache_key, array( key => 1, command => $command, query => $query, remote => 1, rpcinfo => $rpcinfo, cache => array( db => 0, session => 1 ) ) );
570 $result = $resultHandle->getAttributes();
571 return $result;
572 */
573
574 // V3:
575 // $this->set_handler( $proxy );
576
577 // V4: use _component_name & _component_options (proposal from GenericPage)
578 // $this->_component_name = ...
579 // $this->create_handler();
580
581
582 /**
583 * <!-- Autodia -->
584 * can do: (this is metadata supplied for Autodia, don't delete!)
585 * $adapter = new DataSource_Adapter_phpHtmlLib_DataListSource()
586 *
587 */
588
589 // V1:
590 //$this->create_adapter($adapter_module, $this->function, $this->arguments);
591
592 // V2: FIXME - better use V1?
593 $adapter = php::mkComponent($this->get_adapter_module(), $this->get_adapter_options());
594 $this->set_adapter($adapter);
595
596
597
598
599 }
600
601 function make_adapter_transparent() {
602
603 // ... known from Site::Adapter::php::Class:
604
605 // At this place the Adapter becomes a Proxy.
606 // This functionality currently correlates to the
607 // name of our ancestor, DesignPattern::AdapterProxy.
608 // FIXME: move this code to its namespace!!!
609 // FIXME: rename to set_proxy...
610
611 // The reason this has to occour here is required
612 // by the TransparentProxy to actually make the
613 // _handler (_proxy) transparent later....
614 //$this->set_proxy( $this->get_adapter() );
615 }
616
617 /**
618 * Set the metadata information
619 * (a DataSource::Locator) we will use
620 * to build encapsulated instances
621 * of both a Proxy and an Adapter.
622 *
623 * @param LocatorMetadataHash array -
624 *
625 */
626 function set_metadata( &$locator ) {
627 $this->_locator = &$locator;
628 }
629
630 function &get_metadata() {
631 return $this->_locator;
632 }
633
634
635 /**
636 * Set the query metadata hash we will feed *completely*
637 * to an encapsulated Proxy instance.
638 *
639 * @param QueryDeclaration array -
640 *
641 */
642 function set_query( $query ) {
643 $this->_query = $query;
644 }
645
646 /**
647 * Issue remote/proxy call
648 * Stolen from Application_AbstractBackend::_remote_method (RefactoringProposal?)
649 * Tweaked a bit: proxy package now taken from $this->_handler_name
650 *
651 * Create a new instance of a proxy and store it for later reuse.
652 * Read the locator metadata hash and create
653 * the proxy handler instance using passed-in name.
654 *
655 * @param string - $proxy_name (namespaced classname - perl syntax - e.g.: Data::Driver::Proxy)
656 *
657 */
658 function datasource_handler_call() {
659
660
661 // 1. read args and build cache key
662
663 $arg_list = func_get_args();
664 $command = array_shift($arg_list);
665 $cache_key = join("-", array(session_id(), $command, join('_', $arg_list) ));
666 //print "cache_key: $cache_key<br>";
667
668 // FIXME: what if arg_list still contains more elements after doing this?
669 $query = array_shift($arg_list);
670
671 // 2. prepare proxy-options (read from locator)
672
673 //print "this: " . Dumper($this);
674 //exit;
675
676 // read from locator metadata
677 //$proxy_name = $this->_locator[metadata][package];
678
679 // V1:
680 //$rpcinfo = array( Host => $this->_locator[metadata][Host], Port => $this->_locator[metadata][Port] );
681
682 // V2:
683 $rpcinfo = $this->_locator->get_metadata();
684
685 // FIXME! implement this into Data::Driver::RPC::Remote!
686 //$rpcinfo[to_latin] = 1;
687
688 // FIXME! patch query
689 if (sizeof($query) == 1) {
690 $query = $query[0];
691 }
692
693 //print "query: " . Dumper($query);
694
695 // !!! use DesignPattern::Proxy here !!!
696 // $proxy = new DesignPattern_Proxy($proxy_name, ...)
697 // or:
698 // $proxy = mkObject('DesignPattern::Proxy');
699 // $this->set_handler( $proxy );
700 // or:
701 // $proxy = mkObject('DesignPattern::Proxy');
702 // $proxy->
703 // $this->set_handler( $proxy );
704
705
706
707 //$this->set_component_name( $proxy_name );
708 $this->set_component_options( $cache_key, array( key => 1, command => $command, query => $query, remote => 1, rpcinfo => $rpcinfo, cache => array( db => 0, session => 0 ) ) );
709 //print Dumper($this);
710 //exit;
711
712 $this->create_proxy();
713
714 //print Dumper($this);
715 //exit;
716
717 /*
718 // -------------------- clone this & modify ----------
719 $proxy = mkObject($proxy_name, $cache_key, array( key => 1, command => $command, query => $query, remote => 1, rpcinfo => $rpcinfo, cache => array( db => 0, session => 1 ) ) );
720 $this->set_handler( $proxy );
721 //$result = $resultHandle->getAttributes();
722 //return $result;
723 //$this->_result = $resultHandle->getAttributes();
724 //$this->_result = $this->_handler->getAttributes();
725 // -------------------- clone this & modify ----------
726 */
727
728 }
729
730
731 function datasource_handler_buildoptions() {
732
733 //print Dumper($this->_query);
734 //exit;
735
736 // make up a command from metadata
737 // FIXME: abstract this some more (e.g. via a CommandMapper|Registry)
738 switch ($this->_query[metatype]) {
739 case 'data':
740 $command = 'queryData';
741
742 //$command = 'getObjects'; // FIXME!!!
743 //$this->_locator->set_option('metadata.command', $command);
744 /*
745 $args = array();
746 switch ($this->_query[vartype]) {
747 case 'objects':
748 if (!$this->_query[classname]) {
749 $msg = "_query[vartype] == 'objects' requires _query[classname]";
750 user_error("DataSource::Generic: query_data() - failed: " . $msg);
751 }
752 array_push($args, $this->_query[classname]);
753 break;
754 }
755 */
756 $query_args = array();
757
758 $msg_prefix = "DataSource::Generic::datasource_handler_buildoptions failed: ";
759 switch ($this->_query[abstract_type]) {
760 case 'item':
761 if (!$this->_query[nodename] && $this->_query[action] != 'create') {
762 $msg = "_query[vartype] == 'objects' requires _query[nodename]";
763 user_error($msg_prefix . $msg);
764 } elseif($this->_query[action] == 'create' && $this->_query[parent]) {
765 if($this->_query[nodename]) { $query_args[node_class] = $this->_query[nodename]; }
766 if($this->_query['hash_key']) { $query_args['hash_key'] = $this->_query['hash_key']; }
767 $query_args[nodename] = $this->_query[ident];
768 $query_args[parent][guid] = $this->_query[parent][guid];
769 $query_args[parent][nodename] = $this->_query[parent][nodename];
770 } elseif($this->_query[parent]) {
771 $query_args[guid] = $this->_query[ident];
772 $query_args[nodename] = $this->_query[nodename];
773 $query_args[parent][guid] = $this->_query[parent][guid];
774 $query_args[parent][nodename] = $this->_query[parent][nodename];
775 } else {
776 $query_args[guid] = $this->_query[ident];
777 $query_args[nodename] = $this->_query[nodename];
778 // 2003-11-17 NEW: use expand flag for real obj expand at backend
779 if ($this->_query[expand]) {$query_args[expand] = 1; }
780 }
781 //print "generic_source->debug: args " . Dumper($query_args) . "<br>";
782 break;
783 case 'list':
784 if (!$this->_query[nodename]) {
785 $msg = "_query[vartype] == 'objects' requires _query[nodename]";
786 user_error($msg_prefix . $msg);
787 } elseif($this->_query[parent]) {
788 //if($this->_query[nodename]) { $query_args[node_class] = $this->_query[nodename]; }
789 //if($this->_query['hash_key']) { $query_args['hash_key'] = $this->_query['hash_key']; }
790 //$query_args[nodename] = $this->_query[ident];
791 $query_args[parent][guid] = $this->_query[parent][guid];
792 $query_args[parent][nodename] = $this->_query[parent][nodename];
793 }
794 //array_push($query_args, $this->_query[nodename]);
795 $query_args[nodename] = $this->_query[nodename];
796 if($this->_query[list_meta]) { $query_args[list_meta] = $this->_query[list_meta]; }
797 if(is_array($this->_query[owner])) { $query_args[owner] = $this->_query[owner]; }
798 break;
799 case 'tree':
800 /*
801 if (!$this->_query[nodename]) {
802 $msg = "_query[vartype] == 'objects' requires _query[nodename]";
803 user_error($msg_prefix . $msg);
804 }
805 */
806 $query_args[guid] = $this->_query[ident];
807 //$query_args[nodename] = $this->_query[nodename];
808 break;
809 default:
810 $msg = "\$this->_query[abstract_type] could not be dispatched as 'item', 'list' or 'tree'.";
811 user_error($msg_prefix . $msg);
812 break;
813 }
814
815 // filter???
816 //print "Filter: " . Dumper($this->_query[filter]) . "<br>";
817 if ($this->_query[filter]) {
818 $query_args[filter] = $this->_query[filter];
819 }
820
821 // dispatch action
822 //print "Action: " . $this->_query[action] . "<br>";
823 if ($this->_query[action] == 'write') {
824 $query_args[action] = $this->_query[action];
825 $query_args[data] = $this->_query[data];
826 } elseif ($this->_query[action] == 'delete') {
827 $query_args[action] = $this->_query[action];
828 } elseif ($this->_query[action] == 'create') {
829 $query_args[action] = $this->_query[action];
830 } elseif ($this->_query[action] == 'select') {
831 $query_args[action] = $this->_query[action];
832 }
833
834 $args = array(
835 'data_type' => $this->_query[abstract_type],
836 'query_args' => $query_args
837 );
838 break;
839
840 // querySchema
841 case 'schema':
842 //print "Testing schema:" . "<br>";
843 $command = 'querySchema';
844 $args = array( $this->_query[filter] );
845 break;
846
847 // remoteMethod
848 case 'method':
849 $command = $this->_query[method];
850 //$args = $this->_query[args];
851 // FIX
852 $args = array( $this->_query[args] );
853 break;
854
855 }
856
857
858 // FIXME: bad behaviour?
859 if (!is_array($args)) { $args = array( $args ); }
860
861 //print Dumper($args);
862
863 /*
864 $this->_query[rpc_command] = $command;
865 $this->_query[rpc_args] = $command;
866 */
867
868 // methods!!!
869 $this->_locator->_call[_method] = $command;
870 $this->_locator->_call[_arguments] = $args;
871
872 //$adapter = $this->get_adapter();
873
874 // trace
875 /*
876 print Dumper(null, '<b>= = = = = = = = = = = = = = = = = = = = = =</b>');
877 print Dumper('datasource_handler_buildoptions', array(
878 "_locator" => $this->_locator,
879 "_query" => $this->_query,
880 "command" => '<b>' . $command . "</b>",
881 "args" => $args
882 ));
883 */
884
885 /*
886 $this->_handler_options = array(
887 method => $command,
888 args => $args,
889 );
890 */
891
892 }
893
894
895
896 function &fetch_result() {
897
898 //print Dumper($this);
899
900 $this->datasource_handler_buildoptions();
901
902 $call = $this->_locator->get_call();
903
904 //print Dumper($call);
905 //return;
906
907 // pre-flight checks
908 if (!$call[method]) {
909 $msg = "Remote method is empty, please pass in proper metadata or check configuration.";
910 user_error("DataSource::Generic: query_data() - failed: " . $msg);
911 return;
912 }
913
914 //print "fetch_result: this->_handler=" . Dumper($this->_handler);
915
916 // do remote call here and get result
917 // FIXME: handle synchronous/asynchronous mode here!!!
918 $this->datasource_handler_call($call[method], $call[args]);
919
920
921 // TODO: ... = $this->poll_handler_result and $this->get_handler_result
922 $proxy = $this->get_proxy();
923 //HACK 2004-10-07: page-filter done by backend now,
924 // before offset values filled with empty arrays
925 //$this->_result = $proxy->getResult();
926 $result = $proxy->getResult();
927 if($result['total_rows']) {
928 // debug
929 //print "result: " . Dumper($result);
930 $this->_result_count = $result['total_rows'];
931 if($result[offset]) {
932 $result_new = array();
933 for($i=0;$i<$result[offset];$i++) {
934 array_push($result_new, array());
935 }
936 foreach($result['payload'] as $key => $value) {
937 array_push($result_new, $value);
938 }
939 $this->_result = $result_new;
940 } else {
941 $this->_result = $result['payload'];
942 }
943 } else {
944 $this->_result = $result;
945 $this->_result_count = sizeof($this->_result);
946 }
947 //print "result: " . Dumper($this->_result);
948 //print "result: " . Dumper($this->_result); exit;
949
950
951 // trace
952 //if (constants::get('VERBOSE') && $this->_debug[notice]) {
953 if (constants::get('VERBOSE') or constants::get('ERRORS_ONLY')) {
954 //print "_result = " . Dumper($this->_result);
955 //print "<div><b><font color=\"darkgreen\">Debug:</font></b> DataSource::Generic->_result_count = <b>" . $this->_result_count . "</b></div>";
956 $this->draw_status_box();
957 }
958
959 return $this->_result;
960
961 }
962
963 function draw_status_box() {
964
965 static $boxcount;
966
967 $boxcount++;
968
969 $box = container();
970
971 // box style
972 $style = container(
973 html_style("text/css", '.boxlabel_darkgreen { color: darkgreen; font-weight:bold; }'),
974 html_style("text/css", '.box_dsg { background: #20ab39; color: white; border: 2px black groove; width:640px; padding:10px; margin:40px; }')
975 );
976 $box->add( $style );
977
978 // box content
979 $statusbox = html_div('box_dsg');
980 $statusbox->add( html_b("DataSource::Generic"), html_br() );
981 $locatorbox = html_div('box_dsg');
982 $locatorbox->set_id("locatorbox_$boxcount");
983 $locatorbox->add( Dumper($this->_locator) );
984
985 // FIXME: ie/mozilla?
986 //$locatorbox->set_style('display:none;');
987 //$locatorbox->set_style('visibility:hidden;');
988 // already duplicate inside Tracer!!!
989 $locatorbox->set_style('visibility:hidden; position:absolute; z-index:1; margin-top:30px; padding:5px;');
990
991 $statusbox->add( html_span('boxlabel_darkgreen', "Locator:"), link::js_function( 'toggleVisibility', array("locatorbox_$boxcount"), '[show]'), $locatorbox, html_br() );
992 $call = $this->_locator->get_call();
993 $statusbox->add( html_span('boxlabel_darkgreen', "Method:"), $call[method], html_br() );
994 if (sizeof($call[args])) {
995 $statusbox->add( html_span('boxlabel_darkgreen', "Arguments:"), Dumper($call[args]), html_br() );
996 }
997 $statusbox->add( html_span('boxlabel_darkgreen', "Count:"), $this->get_result_count(), html_br() );
998 $box->add( $statusbox );
999
1000 //print $box->render();
1001 trace( $box );
1002
1003 }
1004
1005
1006 function &query_data() {
1007 //print "query!<br/>";
1008 return $this->fetch_result();
1009 //$this->handle_result();
1010 }
1011
1012 function query_schema() {
1013 user_error("FIXME: query_schema");
1014 // $this->datasource_handler_call( ... );
1015 }
1016
1017 function &get_result() {
1018 return $this->_result;
1019 }
1020
1021 function get_result_count() {
1022 return $this->_result_count;
1023 }
1024
1025 }
1026
1027 ?>

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