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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show 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 <?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: 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 *
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
100 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
145 $this->trace = 0;
146
147 $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 if ($this->trace) {
290 //print "_result = " . Dumper($this->_result);
291 print "_result - count = " . sizeof($this->_result) . "<br/>";
292 }
293
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