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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide 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 joko 1.1 <?php
2     /**
3     * This file contains the ProxyDataSource child class
4 joko 1.3 * that uses the Data::Driver::Proxy object to talk
5     * to a remote rpc server.
6 joko 1.1 *
7     * @author Andreas Motl <andreas.motl@ilo.de>
8     * @package phpHtmlLib
9 joko 1.3 * @module ProxyDataSource
10     *
11 joko 1.1 */
12    
13     /**
14 joko 1.4 * $Id: ProxyDataSource.inc,v 1.3 2003/03/01 15:36:11 joko Exp $
15 joko 1.2 *
16     * $Log: ProxyDataSource.inc,v $
17 joko 1.4 * 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 joko 1.3 * Revision 1.2 2003/03/01 04:50:27 joko
22     * encapsulated all output into tracing mode
23     * disabled tracing
24     *
25 joko 1.2 * Revision 1.1 2003/03/01 03:10:40 joko
26     * + initial commit
27 joko 1.1 *
28     *
29     */
30    
31     /**
32     * This requires the MemoryDataSource base class
33     *
34     */
35 joko 1.3 // 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 joko 1.1
45     /**
46     * Have to have PEAR and DB included
47     * the pear dir must be in the
48     * include path.
49     */
50 joko 1.3 // require_once("PEAR.php"); // FIXME: what about PEAR::XML::RPC?
51     // require_once("DB.php");
52 joko 1.1
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 joko 1.3 *
68     * !!!!!! refactor this to Data::Driver::Proxy !!!!!! <-----------------
69     *
70 joko 1.1 * 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 joko 1.3 * --- 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 joko 1.1 * 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 joko 1.3 * @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 joko 1.1 * @package phpHtmlLib
121 joko 1.3 * @module ProxyDataSource
122     *
123 joko 1.1 */
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 joko 1.2
134 joko 1.1 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 joko 1.3 *
141 joko 1.1 */
142     var $_locator = NULL;
143    
144 joko 1.3
145 joko 1.1 /**
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 joko 1.3 *
150 joko 1.1 */
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 joko 1.3 *
163 joko 1.1 */
164     var $_proxy = NULL;
165    
166 joko 1.3
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 joko 1.1 /**
181     * this holds the query result from the
182     * Data::Driver::Proxy->queryXyz() call
183     *
184     */
185     var $_result = NULL;
186    
187 joko 1.3 /**
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 joko 1.1
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 joko 1.2
207 joko 1.1 $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 joko 1.3 function do_proxy_call() {
256 joko 1.1
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 joko 1.3 function build_proxy_options() {
303    
304 joko 1.1 // 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 joko 1.3 $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 joko 1.1
348     // pre-flight checks
349 joko 1.3 if (!$method) {
350 joko 1.1 $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 joko 1.3
355 joko 1.1 // do remote call here and get result
356     // FIXME: handle synchronous/asynchronous mode here!!!
357 joko 1.3 $this->do_proxy_call($method, $args);
358 joko 1.1 // TODO: ... = $this->poll_proxy_result and $this->get_proxy_result
359     $this->_result = $this->_proxy->getAttributes();
360    
361     // trace
362 joko 1.3 if ($this->_debug[notice]) {
363 joko 1.2 //print "_result = " . Dumper($this->_result);
364     print "_result - count = " . sizeof($this->_result) . "<br/>";
365     }
366 joko 1.1
367 joko 1.3 }
368 joko 1.1
369    
370 joko 1.3 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 joko 1.1
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 joko 1.3 $this->fetch_result();
389 joko 1.1 //print Dumper($this->_result);
390     //print Dumper($this->_result[0]);
391     //exit;
392    
393     //$this->_get_header();
394     }
395    
396 joko 1.3
397     function O_get_header() {
398 joko 1.1 //$this->do_prequery();
399     // FIXME: prevent multi-calls by base class
400 joko 1.3 $this->fetch_result();
401 joko 1.1 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 joko 1.3
412    
413    
414    
415    
416    
417    
418    
419 joko 1.1
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