/[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.2 - (hide annotations)
Sat Mar 1 04:50:27 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.1: +13 -4 lines
encapsulated all output into tracing mode
disabled tracing

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

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