/[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.1 - (hide annotations)
Sat Mar 1 03:10:40 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
+ initial commit

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

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