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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sun Mar 2 01:05:13 2003 UTC (21 years, 6 months ago) by joko
Branch: MAIN
Changes since 1.1: +10 -104 lines
- purged old code

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

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