/[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.3 - (hide annotations)
Sat Mar 1 15:36:11 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.2: +122 -57 lines
+ debugging
+ renamed some methods regarding new proposal (build_proxy_options, fetch_result, etc.)

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

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