/[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.28 - (show annotations)
Thu Oct 7 14:11:28 2004 UTC (19 years, 9 months ago) by jonen
Branch: MAIN
Changes since 1.27: +30 -3 lines
+ added HACK related to DataList-filters which are mapped to backend now (page-control!)

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

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