1
|
<?php
|
2
|
|
3
|
require_once($help_functions);
|
4
|
require_once($model_logger.'/Logger.php');
|
5
|
Logger::configure($model_logger.'/log4php.xml');
|
6
|
require_once("paths.php");
|
7
|
require "./predis/autoload.php";
|
8
|
|
9
|
class MYDB {
|
10
|
|
11
|
private $db;
|
12
|
public $stmts = array();
|
13
|
private $schema;
|
14
|
private $facts = array();
|
15
|
private $metadata = array();
|
16
|
private $dimensions = array();
|
17
|
private $log;
|
18
|
private $local_log = array();
|
19
|
private $schema_file;
|
20
|
|
21
|
private $cache = null;
|
22
|
|
23
|
//-------------------------------------------------------------------------------------\\
|
24
|
//-------------------------------------------------------------------------------------\\
|
25
|
//------------------------------CONSTRUCT, SET UP AND FUNCTION-------------------------\\
|
26
|
//-------------------------------------------------------------------------------------\\
|
27
|
//-------------------------------------------------------------------------------------\\
|
28
|
function __construct() {
|
29
|
|
30
|
global $redis_host;
|
31
|
global $redis_port;
|
32
|
global $redis_scheme;
|
33
|
|
34
|
// this creates a logger named "MYDB"
|
35
|
$this->log = Logger::getLogger(__CLASS__);
|
36
|
|
37
|
if(class_exists("Predis\Client")){
|
38
|
|
39
|
try {
|
40
|
|
41
|
Predis\Autoloader::register();
|
42
|
$this->cache = new Predis\Client(array(
|
43
|
"scheme" => $redis_scheme,
|
44
|
"host" => $redis_host,
|
45
|
"port" => $redis_port,
|
46
|
"persistent" => 1,
|
47
|
"read_write_timeout" => 0));
|
48
|
|
49
|
$this->cache->connect();
|
50
|
|
51
|
$this->log->info("redis host: ".$redis_host);
|
52
|
$this->log->info("redis port: ".$redis_port);
|
53
|
|
54
|
} catch(Exception $e) {
|
55
|
$this->log->error("Error connecting to Redis server: ".$e->getMessage());
|
56
|
$this->cache = null;
|
57
|
}
|
58
|
|
59
|
} else {
|
60
|
$this->log->info("Class Predis does not exist\n");
|
61
|
}
|
62
|
}
|
63
|
|
64
|
// initialises the arrays containing the warehouse schema, via an xml that describes them
|
65
|
//TODO: insert checks on whether the data in the xml are correct (get schema from db)
|
66
|
function loadSchema($file = null) {
|
67
|
if(file_exists($file)) {
|
68
|
$json = file_get_contents($file);
|
69
|
//$this->log->info('schema of database: '.json_encode((array) simplexml_load_string($json)));
|
70
|
$this->schema = json_decode(json_encode((array) simplexml_load_string($json)),1);
|
71
|
}
|
72
|
else {
|
73
|
echo "loadSchema: could not find the xml";
|
74
|
$this->log->error('loadSchema: could not find the xml');
|
75
|
return -1;
|
76
|
}
|
77
|
foreach ($this->schema['table'] as $table) {
|
78
|
switch ($table['type']) {
|
79
|
case 'fact': array_push($this->facts,$table);
|
80
|
break;
|
81
|
//case 'm': array_push($this->metadata,$table);
|
82
|
// break;
|
83
|
default: array_push($this->dimensions,$table);
|
84
|
break;
|
85
|
}
|
86
|
}
|
87
|
$this->log->info("loaded schema");
|
88
|
}
|
89
|
|
90
|
|
91
|
function doConnect($file) {
|
92
|
try {
|
93
|
switch($GLOBALS['type']){
|
94
|
case 'postgres':
|
95
|
$this->db = new PDO('pgsql:host='.$GLOBALS['host'].';port=5432;dbname='.$GLOBALS['db_name'].';user='.$GLOBALS['username'].';password='.$GLOBALS['password']);
|
96
|
break;
|
97
|
case 'sqlite':
|
98
|
$this->db = new PDO('sqlite:'.$GLOBALS['head'].$GLOBALS['db_name']);
|
99
|
break;
|
100
|
default:
|
101
|
echo "not known database type\n";
|
102
|
break;
|
103
|
}
|
104
|
} catch(Exception $e){
|
105
|
echo "oops..".$e->getMessage()."\n";
|
106
|
$this->log->fatal($e->getMessage());
|
107
|
return false;
|
108
|
}
|
109
|
$this->schema_file = $file;
|
110
|
$this->loadSchema($file);
|
111
|
}
|
112
|
|
113
|
function doDisconnect($save = false) {
|
114
|
if($save) {
|
115
|
$fp = fopen($this->schema_file,"w");
|
116
|
$data = "<schema>\n".toxml($this->schema,"schema",1)."\n</schema>\n";
|
117
|
fwrite($fp,$data);
|
118
|
fclose($fp);
|
119
|
}
|
120
|
$this->db = null;
|
121
|
}
|
122
|
|
123
|
function beginTrans() {
|
124
|
$this->db->beginTransaction();
|
125
|
}
|
126
|
|
127
|
function doCommit() {
|
128
|
$this->db->commit();
|
129
|
}
|
130
|
|
131
|
function doQuery($query, $fetchMode=PDO::FETCH_BOTH){
|
132
|
|
133
|
if($this->cache != null){
|
134
|
|
135
|
$myKey = md5($query);
|
136
|
$this->log->debug("Searching for key: ".$myKey);
|
137
|
|
138
|
if($this->cache->exists($myKey)) {
|
139
|
|
140
|
$results = $this->cache->hget($myKey, "results");
|
141
|
return json_decode($results, true);
|
142
|
|
143
|
} else {
|
144
|
|
145
|
$this->log->debug("not found in cache");
|
146
|
$results = $this->doQueryNoCache($query, $fetchMode);
|
147
|
$this->log->info("adding in cache. key: ".$myKey);
|
148
|
|
149
|
if(isset($_GET['persistent']))
|
150
|
$persistent = $_GET['persistent'];
|
151
|
else
|
152
|
$persistent = true; //default value is true if not provided
|
153
|
|
154
|
if(($this->cache->hmset($myKey, array("query" => $query, "results" => json_encode($results), "persistent" => $persistent, "fetchMode" => $fetchMode))) == false) {
|
155
|
$this->log->info("adding key ".$myKey." in cache failed."); //predis
|
156
|
} else {
|
157
|
$this->cache->save();
|
158
|
}
|
159
|
return $results;
|
160
|
}
|
161
|
} else {
|
162
|
return $this->doQueryNoCache($query, $fetchMode);
|
163
|
}
|
164
|
}
|
165
|
|
166
|
function doQueryNoCache($query, $fetchMode=PDO::FETCH_BOTH) {
|
167
|
|
168
|
$stmt = $this->db->query($query);
|
169
|
if(!$stmt){
|
170
|
$arr = $this->db->errorInfo();
|
171
|
$this->log->error($arr[2]);
|
172
|
return null;
|
173
|
}
|
174
|
return $stmt->fetchAll($fetchMode);
|
175
|
}
|
176
|
|
177
|
function doPrepare($query){
|
178
|
$stmt = $this->db->prepare($query);
|
179
|
if(!$stmt){
|
180
|
$arr = $this->db->errorInfo();
|
181
|
$this->log->error($arr[0]." ".$arr[1]." ".$arr[2]);
|
182
|
return false;
|
183
|
}
|
184
|
return $stmt;
|
185
|
}
|
186
|
|
187
|
function doExecute($stmt){
|
188
|
if(!$stmt->execute()){
|
189
|
$arr = $stmt->errorInfo();
|
190
|
$this->log->error($arr[2]);
|
191
|
return false;
|
192
|
}
|
193
|
return $stmt;
|
194
|
}
|
195
|
|
196
|
//-------------------------------------------------------------------------------------\\
|
197
|
//-------------------------------------------------------------------------------------\\
|
198
|
//------------------------------CHECKS, GETTERS, SETTERS-------------------------------\\
|
199
|
//-------------------------------------------------------------------------------------\\
|
200
|
//-------------------------------------------------------------------------------------\\
|
201
|
|
202
|
public function printSchema() {
|
203
|
print_r($this->schema);
|
204
|
}
|
205
|
|
206
|
public function getSchema() {
|
207
|
if(isset($this->schema))
|
208
|
return $this->schema;
|
209
|
return null;
|
210
|
}
|
211
|
|
212
|
public function getFacts() {
|
213
|
$list = $this->doQuery("select tableName from defaults order by tableorder");
|
214
|
if($list != null){
|
215
|
$sorted = array();
|
216
|
if(isset($this->facts)) {
|
217
|
for($i=0;$i<count($list);$i++) {
|
218
|
foreach($this->facts as $fact){
|
219
|
if($fact['name'] == $list[$i][0]){
|
220
|
$sorted[] = $fact;
|
221
|
break;
|
222
|
}
|
223
|
}
|
224
|
}
|
225
|
return $sorted;
|
226
|
}
|
227
|
}
|
228
|
else
|
229
|
return $this->facts;
|
230
|
}
|
231
|
|
232
|
public function getDimensions() {
|
233
|
if(isset($this->dimensions)) {
|
234
|
return $this->dimensions;
|
235
|
}
|
236
|
return null;
|
237
|
}
|
238
|
|
239
|
public function getFactsNames() {
|
240
|
$names = array();
|
241
|
if(isset($this->facts)) {
|
242
|
foreach($this->facts as $fact) {
|
243
|
array_push($names,$fact['name']);
|
244
|
}
|
245
|
return $names;
|
246
|
}
|
247
|
return null;
|
248
|
}
|
249
|
|
250
|
function getType($oldType) {
|
251
|
switch ($oldType) {
|
252
|
case 'int':
|
253
|
case 'double':
|
254
|
return 'number';
|
255
|
break;
|
256
|
case 'varchar':
|
257
|
case 'datetime':
|
258
|
return 'string';
|
259
|
break;
|
260
|
case 'bool':
|
261
|
return 'boolean';
|
262
|
break;
|
263
|
default:
|
264
|
return false;
|
265
|
}
|
266
|
}
|
267
|
|
268
|
/*returns an array with the triplet (name,type,view) for each of the keys of the dimension table
|
269
|
or false on failure
|
270
|
type is either number, string or boolean //? need to add more ?*/
|
271
|
function findKeys($table) {
|
272
|
$myarray = array();
|
273
|
if($table == false) {
|
274
|
$this->log->error('findKeys: no table indicated');
|
275
|
return false;
|
276
|
}
|
277
|
if(is_array($table['key'])) {
|
278
|
foreach($table['key'] as $key) {
|
279
|
$keyInfo = $this->findOneField($table,$key,'attrib');
|
280
|
array_push($myarray,$keyInfo);
|
281
|
}
|
282
|
}
|
283
|
else {
|
284
|
$keyInfo = $this->findOneField($table,$table['key'],'attrib');
|
285
|
array_push($myarray,$keyInfo);
|
286
|
}
|
287
|
return $myarray;
|
288
|
}
|
289
|
|
290
|
//returns an array with the tetraplet (name,type,view,data) for each of the meas of the fact table or false on failure
|
291
|
//type is either number, string or boolean //? need to add more ?
|
292
|
function findMeas($table) {
|
293
|
$myarray = array();
|
294
|
if($table == false) {
|
295
|
$this->log->error('findMeas: no table indicated');
|
296
|
return false;
|
297
|
}
|
298
|
if(isset($table['meas'][0])) {
|
299
|
foreach($table['meas'] as $meas) {
|
300
|
if(isset($meas['view'])) {
|
301
|
$view = $meas['view'];
|
302
|
}
|
303
|
else
|
304
|
$view = $meas['name'];
|
305
|
array_push($myarray,array($meas['name'],$view,$meas['type'],$meas['data']));
|
306
|
}
|
307
|
}
|
308
|
else {
|
309
|
if(isset($table['meas']['view'])) {
|
310
|
$view = $meas['view'];
|
311
|
}
|
312
|
else
|
313
|
$view = $meas['name'];
|
314
|
array_push($myarray,array($meas['name'],$view,$meas['type'],$meas['data']));
|
315
|
}
|
316
|
return $myarray;
|
317
|
}
|
318
|
|
319
|
function getDims() {
|
320
|
return $this->dimensions;
|
321
|
}
|
322
|
|
323
|
function findOneField($table,$name,$ftype) {
|
324
|
$field = search($table[$ftype],'name',$name);
|
325
|
if(count($field)!=1) {
|
326
|
$this->log->error('error in xml');
|
327
|
return false;
|
328
|
}
|
329
|
|
330
|
$type = $this->getType($field[0]['type']);
|
331
|
|
332
|
if(isset($field[0]['view'])) {
|
333
|
$view = $field[0]['view'];
|
334
|
}
|
335
|
else
|
336
|
$view = $field[0]['name'];
|
337
|
|
338
|
return array($field[0]['name'],$type,$view,$field[0]['data']);
|
339
|
|
340
|
}
|
341
|
|
342
|
function getField($table,$name,$ftype) {
|
343
|
$field = search($table[$ftype],'name',$name);
|
344
|
if(count($field)!=1) {
|
345
|
$this->log->error('error in xml');
|
346
|
return false;
|
347
|
}
|
348
|
|
349
|
return $field[0];
|
350
|
}
|
351
|
|
352
|
function findTable($name,$type) {
|
353
|
if($type == 'dimension') {
|
354
|
$all_matching_files = search($this->dimensions,'name',$name);
|
355
|
}
|
356
|
elseif($type == 'fact') {
|
357
|
$all_matching_files = search($this->facts,'name',$name);
|
358
|
}
|
359
|
else {
|
360
|
$this->log->error('findTable: could not recognise type '.$type);
|
361
|
return false;
|
362
|
}
|
363
|
if(count($all_matching_files)==0) {
|
364
|
$this->log->error('xml file error: table: '.$name.' not found');
|
365
|
return false;
|
366
|
}
|
367
|
$matching_files = search($all_matching_files,'type',$type);
|
368
|
if(count($matching_files)!=1) {
|
369
|
$this->log->error('multiple '.$type.'s with name: '.$name);
|
370
|
return false;
|
371
|
}
|
372
|
return $matching_files[0];
|
373
|
|
374
|
}
|
375
|
|
376
|
//checks if a fact table with exactly the given dimensions exist
|
377
|
function searchWarehousebyDims($dims) {
|
378
|
$flag = false;
|
379
|
|
380
|
foreach($this->facts as $warehouse) {
|
381
|
|
382
|
//if the number of dims is the same as the given and every dim in the list exists in the given then return the warehouse name
|
383
|
if(count($warehouse['dim']) != count($dims)){
|
384
|
continue;
|
385
|
}
|
386
|
foreach($dims as $dim) {
|
387
|
$res = search($warehouse['dim'], 'name', $dim);
|
388
|
if(count($res) != 0) {
|
389
|
$flag = true;
|
390
|
}
|
391
|
else {
|
392
|
$flag = false;
|
393
|
break;
|
394
|
}
|
395
|
}
|
396
|
if($flag == true)
|
397
|
return $warehouse['name'];
|
398
|
}
|
399
|
//not found
|
400
|
return false;
|
401
|
}
|
402
|
|
403
|
/*check if a name is already in use for a fact table
|
404
|
if yes, return false, otherwise, return true*/
|
405
|
function checkName($name) {
|
406
|
if(findTable($name,"fact") != false) {
|
407
|
return true;
|
408
|
}
|
409
|
return false;
|
410
|
}
|
411
|
|
412
|
/*check if a name is already in use for a dimension table
|
413
|
if yes, return true, otherwise, return false*/
|
414
|
function checkDim($name) {
|
415
|
if(findTable($name,"dimension") != false) {
|
416
|
return true;
|
417
|
}
|
418
|
return false;
|
419
|
}
|
420
|
|
421
|
function findTableType($name) {
|
422
|
if($this->findTable($name,"dimension") != false) {
|
423
|
return "dimension";
|
424
|
}
|
425
|
if($this->findTable($name,"fact") != false) {
|
426
|
return "fact";
|
427
|
}
|
428
|
return false;
|
429
|
}
|
430
|
|
431
|
/*check if a list of dims all exist in the schema
|
432
|
returns a list with all dims that don't exist or true
|
433
|
*/
|
434
|
function checkListofDims($dims) {
|
435
|
$non_existent = array();
|
436
|
$flag = true;
|
437
|
foreach($dims as $dim) {
|
438
|
if(checkDim($dim) == true){
|
439
|
array_push($non_existent,$dim);
|
440
|
$flag = false;
|
441
|
}
|
442
|
}
|
443
|
if($flag == true)
|
444
|
return true;
|
445
|
else
|
446
|
return $non_existent;
|
447
|
}
|
448
|
|
449
|
function checkMeas($fact, $meas_name) {
|
450
|
//find the fact table
|
451
|
//if there is a meas with the same name
|
452
|
foreach($this->facts as $table)
|
453
|
if($table['name'] == $fact)
|
454
|
foreach($table['meas'] as $meas) {
|
455
|
if($meas['name'] == $meas_name){
|
456
|
return true;
|
457
|
}
|
458
|
}
|
459
|
return false;
|
460
|
}
|
461
|
|
462
|
function getAllDims() {
|
463
|
$dimnames = array();
|
464
|
foreach($this->dimensions as $dim) {
|
465
|
array_push($dimnames,$dim['name']);
|
466
|
}
|
467
|
return $dimnames;
|
468
|
}
|
469
|
|
470
|
function getDimsFieldsList($tableName) {
|
471
|
$fields = array();
|
472
|
//find the table
|
473
|
$table = $this->findTable($tableName,'dimension');
|
474
|
if($table == false) {
|
475
|
return false;
|
476
|
}
|
477
|
foreach($table['attrib'] as $field) {
|
478
|
if($field['name'] == 'id')
|
479
|
continue;
|
480
|
if(isset($field['analysed'])) {
|
481
|
$fields = array_merge($fields,$this->getDimsFieldsList($field['analysed']));
|
482
|
}
|
483
|
else {
|
484
|
if(isset($field['view']))
|
485
|
$view = $field['view'];
|
486
|
else
|
487
|
$view = $field['name'];
|
488
|
array_push($fields,array($tableName.".".$field['name'],$tableName.".".$view,$field['type'],$field['data']));
|
489
|
}
|
490
|
}
|
491
|
return $fields;
|
492
|
}
|
493
|
|
494
|
function getDimsList($tablename) {
|
495
|
$fields = array();
|
496
|
//find the factable
|
497
|
$table = $this->findTable($tablename,'fact');
|
498
|
if($table == false) {
|
499
|
return false;
|
500
|
}
|
501
|
foreach($table['dim'] as $dim) {
|
502
|
$temp = $this->getDimsFieldsList($dim['name']);
|
503
|
$fields = array_merge($fields, $temp);
|
504
|
}
|
505
|
return $fields;
|
506
|
}
|
507
|
|
508
|
function getDimsKeys($dimName) {
|
509
|
$table = $this->findTable($dimName,'dimension');
|
510
|
if($table == false) {
|
511
|
return false;
|
512
|
}
|
513
|
return $table['key'];
|
514
|
}
|
515
|
|
516
|
//-------------------------------------------------------------------------------------\\
|
517
|
//-------------------------------------------------------------------------------------\\
|
518
|
//----------------------------------DATA READING---------------------------------------\\
|
519
|
//-------------------------------------------------------------------------------------\\
|
520
|
//-------------------------------------------------------------------------------------\\
|
521
|
|
522
|
function getMeasMetadata($table) {
|
523
|
$query = 'select name, source, sourceUrl, definition, unit from Metadata where inTable="'.$table.'"';
|
524
|
$this->log->info("getMeasMetadata -> generated query: ".$query);
|
525
|
$res = $this->doQuery($query);
|
526
|
if($res == null)
|
527
|
return "false";
|
528
|
|
529
|
return $res;
|
530
|
}
|
531
|
|
532
|
/*
|
533
|
gets the name of a fact table and the name of a measurement and returns the minimun, maximum and count distinct values for it
|
534
|
*/
|
535
|
function measRangeData($facttable, $measurement) {
|
536
|
$query = "SELECT min($measurement), max($measurement), count(distinct $measurement) FROM $facttable WHERE $measurement != ''";
|
537
|
$this->log->info("generated query: ".$query);
|
538
|
$res = $this->doQuery($query);
|
539
|
$res=$res[0];
|
540
|
return array($res[0],$res[1],$res[2]);
|
541
|
}
|
542
|
|
543
|
//return the minimun, maximum
|
544
|
function getRangeData($table, $field) {
|
545
|
$query = 'SELECT min("'.$field.'"), max("'.$field.'") FROM "'.$table.'"';
|
546
|
if($GLOBALS['type'] == "sqlite")
|
547
|
$query .= ' WHERE "'.$field.'" != ""';
|
548
|
$this->log->info("generated query: ".$query);
|
549
|
$res = $this->doQuery($query);
|
550
|
$res = $res[0];
|
551
|
return array("min"=>$res[0],"max"=>$res[1]);
|
552
|
}
|
553
|
|
554
|
//return the distinct values
|
555
|
function getDistinctValues($table, $field) {
|
556
|
$query = 'select distinct "'.$field.'" from "'.$table.'" order by "'.$field.'"';
|
557
|
$this->log->info("generated query: ".$query);
|
558
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
559
|
return $res;
|
560
|
}
|
561
|
|
562
|
function getFilterData($table,$field){
|
563
|
$flag = false;
|
564
|
$myDimTable = $this->findTable($table,'dimension');
|
565
|
$myFactTable = $this->findTable($table,'fact');
|
566
|
//is it a dim?
|
567
|
if($myDimTable != false){
|
568
|
//does it have the field?
|
569
|
if(!isAssoc($myDimTable['attrib'])){
|
570
|
foreach($myDimTable['attrib'] as $attrib){
|
571
|
if($attrib['name'] == $field){
|
572
|
$myField = $attrib;
|
573
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
574
|
}
|
575
|
}
|
576
|
}
|
577
|
else{
|
578
|
if($myDimTable['attrib']['name'] == $field){
|
579
|
$myField = $myDimTable['attrib'];
|
580
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
581
|
}
|
582
|
}
|
583
|
}
|
584
|
if($myFactTable != false){
|
585
|
//look in the dims
|
586
|
if(!isAssoc($myFactTable['dim'])){
|
587
|
foreach($myFactTable['dim'] as $dim) {
|
588
|
if($dim['name'] == $field){
|
589
|
$myField = $dim;
|
590
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
591
|
}
|
592
|
}
|
593
|
}
|
594
|
else{
|
595
|
if($myFactTable['dim']['name'] == $field){
|
596
|
$myField = $myFactTable['dim'];
|
597
|
//$flag = true;
|
598
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
599
|
}
|
600
|
}
|
601
|
if(!isAssoc($myFactTable['meas'])){
|
602
|
foreach($myFactTable['meas'] as $meas) {
|
603
|
if($meas['name'] == $field){
|
604
|
$myField = $meas;
|
605
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
606
|
}
|
607
|
}
|
608
|
}
|
609
|
else{
|
610
|
if($myFactTable['meas']['name'] == $field){
|
611
|
$myField = $myFactTable['meas'];
|
612
|
return array_merge(array('type'=>$myField['data'],'data'=>$this->getDistinctValues($table, $field)),$this->getRangeData($table, $field));
|
613
|
}
|
614
|
}
|
615
|
$this->log->error('cannot find field '.$field.' in table '.$table);
|
616
|
return "cannot find field ".$field;
|
617
|
}
|
618
|
|
619
|
$this->log->error("cannot find table ".$table);
|
620
|
return "cannot find table ".$table;
|
621
|
}
|
622
|
|
623
|
function getDefaultData($table) {
|
624
|
$this->log->info("DefaultData -> table:".$table);
|
625
|
if($table !=null && $table!='null') {
|
626
|
$query = 'select * from "defaults" where tablename='."'".$table."'";
|
627
|
}
|
628
|
else{
|
629
|
$query = 'select * from "defaults" where tableorder=(select min(tableorder) from "defaults")';
|
630
|
}
|
631
|
$this->log->info("DefaultData -> query created: ".$query);
|
632
|
$res = $this->doQuery($query);
|
633
|
if($res == null)
|
634
|
return "empty";
|
635
|
|
636
|
$selectedData = array();
|
637
|
$selectedData['table'] = $res[0][0];
|
638
|
$selectedData['fields'] = array();
|
639
|
$selectedData['fields'][0] = array();
|
640
|
$selectedData['fields'][0]['fld'] = $res[0][2];
|
641
|
$selectedData['fields'][0]['agg'] = $res[0][3];
|
642
|
$selectedData['fields'][0]['id'] = 0;
|
643
|
$selectedData['fields'][0]['type'] = "";
|
644
|
$selectedData['fields'][0]['yaxis'] = 1;
|
645
|
$selectedData['xaxis']['name'] = $res[0][1];
|
646
|
$selectedData['xaxis']['agg'] = 'avg';
|
647
|
$selectedData['group'] = '';
|
648
|
$selectedData['color'] = '';
|
649
|
if($this->checkMeas($selectedData['table'], $selectedData['xaxis']['name'])){
|
650
|
$type='scatter';
|
651
|
$selectedData['type'] = 'scatter';
|
652
|
}
|
653
|
else{
|
654
|
$selectedData['type'] = 'chart';
|
655
|
$type = $res[0][5];
|
656
|
}
|
657
|
$selectedData['size'] = $GLOBALS['size'];
|
658
|
return array('selectedData'=>$selectedData,'type'=>$type);
|
659
|
//return array('selectedData'=>$selectedData, 'data'=>$this->getData($selectedData),'type'=>$type);
|
660
|
}
|
661
|
|
662
|
/*
|
663
|
domi tou selectedData:
|
664
|
['table'] = fact table name
|
665
|
['fields'] = [{'fld':field name,'agg':aggregator for the field,'id': de mas noiazei}, ...]
|
666
|
['series'] = [dim field name with the list of the dim tables names that lead to it (eg: Product-Supplier-sup_name), ...]
|
667
|
['group'] = dim field name with the list of the dim tables names that lead to it (eg: Product-Supplier-sup_name) <---will have to group by it and have a series for each value of it
|
668
|
['xaxis'] = {'name': to onoma tou dim h meas pou paei ston x axis, 'agg': o aggregator an einai meas}
|
669
|
['type'](optional)
|
670
|
stin apli periptwsi to series einai panta keno
|
671
|
sto telos exoume tosa series osa fields (to poly 3)
|
672
|
|
673
|
an sto xaxis exoume meas tote exoume scatter plot kai den bazoume to xaxis sto group by
|
674
|
an den exoume series tote den exoume group by kai agnooume ta aggs
|
675
|
*/
|
676
|
/*
|
677
|
domi tou query:
|
678
|
ok select: to xaxis me patera to akribws proigoumeno sto onoma AND ola ta fields me ta aggs tous AND ola ta series me patera to akribws proigoumeno sto onoma
|
679
|
ok from: to table AND ola osa emfanizontai sto series kai to xaxis
|
680
|
where: 1 zeygari gia kathe syndyasmo diplanwn pinakwn pou emfanizetai sto series kai twn arxikwn me to table
|
681
|
(eg: gia to Product-Supplier tha exoume ena zeygari to Product,Supplier kai ena to Facttable,Product)
|
682
|
ok group by: to xaxis kai ola ta series opws akribws kai sto select
|
683
|
ok order by: to xaxis
|
684
|
*/
|
685
|
function makeQueryGroup($sel){//print_r($sel);
|
686
|
$this->log->info("makeQueryGroup");
|
687
|
/*
|
688
|
select agg(field), xaxisfield, groupfield
|
689
|
from facttable, xaxistables, grouptables
|
690
|
where facttable = xaxistables and xaxistables and facttable = groupstables and groupstables
|
691
|
group by groupfield, xaxisfield (ektos ki an einai meas)
|
692
|
order by groupfield, xaxisfield
|
693
|
*/
|
694
|
$isMeas = false;
|
695
|
$field = "";
|
696
|
$xaxisfield = "";
|
697
|
$groupfield = "";
|
698
|
$tables = array();
|
699
|
$tablesPairs = array();
|
700
|
$tables[] = $sel['table'];
|
701
|
/*yaxis*/ //<---- panta measurement
|
702
|
$field = '"'.$sel['fields'][0]['fld'].'"';
|
703
|
/*xaxis*/
|
704
|
$xaxislist = explode("-",$sel['xaxis']['name']);
|
705
|
if($this->checkMeas($sel['table'], $xaxislist[count($xaxislist)-1])){
|
706
|
$isMeas = true;
|
707
|
}
|
708
|
if(!$isMeas){
|
709
|
//an den einai measurement tote einai dimension kai mporei na exei tables
|
710
|
if(count($xaxislist) == 1){ //einai dim alla den analyetai se pinaka
|
711
|
$xaxisfield = '"'.$sel['table'].'"."'.$xaxislist[count($xaxislist)-1].'"';
|
712
|
}
|
713
|
else{
|
714
|
$xaxisfield = '"'.$xaxislist[count($xaxislist)-2].'"."'.$xaxislist[count($xaxislist)-1].'"';
|
715
|
|
716
|
//briskw tous pinakes enan enan kai tous bazw sta pairs alla kai sto xaxistables
|
717
|
for($i=0;$i<count($xaxislist)-1;$i++){
|
718
|
if(!in_array($xaxislist[$i],$tables)){
|
719
|
$tables[] = $xaxislist[$i];
|
720
|
}
|
721
|
if($i == count($xaxislist)-2){
|
722
|
if(!in_array_r(array($sel['table'],$xaxislist[$i]), $tablesPairs)){
|
723
|
$tablesPairs[] = array($sel['table'],$xaxislist[$i]);
|
724
|
}
|
725
|
}
|
726
|
else{
|
727
|
if(!in_array_r(array($xaxislist[$i],$xaxislist[$i+1]),$tablesPairs))
|
728
|
$tablesPairs[] = array($xaxislist[$i],$xaxislist[$i+1]);
|
729
|
}
|
730
|
}
|
731
|
}
|
732
|
}
|
733
|
else {
|
734
|
//einai meas, den kanw tipota
|
735
|
$xaxisfield = '"'.$sel['table'].'"."'.$sel['xaxis']['name'].'"';
|
736
|
$xaxistables = null;
|
737
|
}
|
738
|
/*group*/
|
739
|
//briskw tous pinakes tou group field kai tous bazw enan enan sto table alla kai sta pairs
|
740
|
$grouplist = explode("-",$sel['group']);
|
741
|
if(count($grouplist) == 1){ //einai dim alla den analyetai se pinaka
|
742
|
$groupfield = '"'.$sel['table'].'"."'.$grouplist[count($grouplist)-1].'"';
|
743
|
}
|
744
|
else{
|
745
|
$groupfield = '"'.$grouplist[count($grouplist)-2].'"."'.$grouplist[count($grouplist)-1].'"';
|
746
|
//briskw tous pinakes enan enan kai tous bazw sta pairs alla kai sto xaxistables
|
747
|
for($i=0;$i<count($grouplist)-1;$i++){
|
748
|
if(!in_array($grouplist[$i],$tables)){
|
749
|
$tables[] = $grouplist[$i];
|
750
|
}
|
751
|
if($i == count($grouplist)-2){
|
752
|
if(!in_array_r(array($sel['table'],$grouplist[$i]), $tablesPairs)){
|
753
|
$tablesPairs[] = array($sel['table'],$grouplist[$i]);
|
754
|
}
|
755
|
}
|
756
|
else{
|
757
|
if(!in_array_r(array($grouplist[$i],$grouplist[$i+1]),$tablesPairs))
|
758
|
$tablesPairs[] = array($grouplist[$i],$grouplist[$i+1]);
|
759
|
}
|
760
|
}
|
761
|
}
|
762
|
//steinw to query
|
763
|
$query = "select ";
|
764
|
/*xaxis*/
|
765
|
if($isMeas && $sel['color'] != 'yes'){ // prepei na balw kai ton aggregator
|
766
|
switch($sel['xaxis']['agg']){
|
767
|
case 'none':
|
768
|
case '':
|
769
|
case 'avg':
|
770
|
$query .= " avg(".$xaxisfield.") ";
|
771
|
break;
|
772
|
default:
|
773
|
$query .= $sel['xaxis']['agg']."(".$xaxisfield.") ";
|
774
|
break;
|
775
|
}
|
776
|
}
|
777
|
else{
|
778
|
$query .= " ".$xaxisfield;
|
779
|
}
|
780
|
/*yaxis*/
|
781
|
if($sel['color'] != 'yes')
|
782
|
switch($sel['fields'][0]['agg']){
|
783
|
case 'none':
|
784
|
case '':
|
785
|
case 'avg':
|
786
|
$query .= ", avg(".$field.") ";
|
787
|
break;
|
788
|
default:
|
789
|
$query .= ", ".$sel['fields'][0]['agg']."(".$field.") ";
|
790
|
break;
|
791
|
}
|
792
|
else
|
793
|
$query .= ', '.$field;
|
794
|
|
795
|
/*group*/
|
796
|
$query .= ", ".$groupfield;
|
797
|
|
798
|
$query .= " from ".implode(", ",$tables);
|
799
|
$query .= " where ";
|
800
|
for($i=0;$i<count($sel['fields']);$i++) {
|
801
|
if($i!=0) $query .=" and ";
|
802
|
$query .= '"'.$sel['fields'][$i]['fld'] .'" !=""';
|
803
|
}
|
804
|
|
805
|
if(count($tablesPairs) > 0){
|
806
|
$query .= " and ";
|
807
|
for($i=0;$i<count($tablesPairs);$i++){
|
808
|
$query .= '"'.$tablesPairs[$i][0].'"."'.$tablesPairs[$i][1].'"="'.$tablesPairs[$i][1].'".id';
|
809
|
if($i!=count($tablesPairs)-1) $query .= "and ";
|
810
|
else $query .= " ";
|
811
|
}
|
812
|
}
|
813
|
else $query .= ' ';
|
814
|
if($sel['color'] != 'yes'){
|
815
|
$query .= "group by ".$groupfield;
|
816
|
if(!$isMeas){
|
817
|
$query .=", ".$xaxisfield;
|
818
|
}
|
819
|
}
|
820
|
$query .= " order by ".$groupfield.", ".$xaxisfield;
|
821
|
$this->log->info("generated query: ".$query);
|
822
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
823
|
if($isMeas) $returnType = 'scatter';
|
824
|
else $returnType = 'chart';
|
825
|
return array('type'=>$returnType,'data'=>$res,'accomDims'=>$dimsList['fields']);
|
826
|
}
|
827
|
|
828
|
function getData($sel){
|
829
|
$this->log->info("getting data");
|
830
|
$xaxislist = explode("-",$sel['xaxis']['name']);
|
831
|
$groups = array();
|
832
|
$brsels = array(); $queries = array();
|
833
|
$breakflag = false;
|
834
|
//check if we need to break the query to many (if there are filters that apply to only one field)
|
835
|
if(count($sel['fields']) > 1){
|
836
|
for($i=0;$i<count($sel['filters']);$i++)
|
837
|
if(isset($sel['filters'][$i]['to']) && $sel['filters'][$i]['to'] != -1){
|
838
|
if(!in_array($sel['filters'][$i]['to'],$groups))
|
839
|
$groups[] = $sel['filters'][$i]['to'];
|
840
|
$breakflag = true;
|
841
|
}
|
842
|
for($i=0;$i<count($sel['having']);$i++)
|
843
|
if(isset($sel['having'][$i]['to']) && $sel['having'][$i]['to'] != -1){
|
844
|
if(!in_array($sel['having'][$i]['to'],$groups))
|
845
|
$groups[] = $sel['having'][$i]['to'];
|
846
|
$breakflag = true;
|
847
|
}
|
848
|
}
|
849
|
if($breakflag){
|
850
|
$this->log->info("NEED TO BREAK!");
|
851
|
//will break the query into as many as the different values in the filters and havings to attribute -> count($groups)
|
852
|
$brsels[] = $this->clearselections($sel,$groups,-1,0);
|
853
|
if($this->checkMeas($sel['table'], $xaxislist[count($xaxislist)-1]))
|
854
|
$queries[] = $this->scatterData($brsels[0],false);
|
855
|
else
|
856
|
$queries[] = $this->chartData($brsels[0],false);
|
857
|
for($i=0;$i<count($groups);$i++){
|
858
|
$brsels[] = $this->clearselections($sel,$groups,$groups[$i],$i+1);
|
859
|
|
860
|
if($this->checkMeas($sel['table'], $xaxislist[count($xaxislist)-1]))
|
861
|
$queries[] = $this->scatterData($brsels[$i+1],false);
|
862
|
else
|
863
|
$queries[] = $this->chartData($brsels[$i+1],false);
|
864
|
}
|
865
|
|
866
|
$this->log->info("selections: ".print_r($brsels,true));
|
867
|
$this->log->info("user selections updated: ".print_r($sel,true));
|
868
|
$this->log->info("queries: ".print_r($queries,true));
|
869
|
//get all the queries and combine them to one
|
870
|
if($this->checkMeas($sel['table'], $xaxislist[count($xaxislist)-1]))
|
871
|
return $this->makeSuperQuery($queries,$sel,"scatter");
|
872
|
else
|
873
|
return $this->makeSuperQuery($queries,$sel,"chart");
|
874
|
}
|
875
|
else{
|
876
|
$this->log->info("NO NEED TO BREAK!");
|
877
|
if($this->checkMeas($sel['table'], $xaxislist[count($xaxislist)-1]))
|
878
|
return $this->scatterData($sel);
|
879
|
else
|
880
|
return $this->chartData($sel);
|
881
|
}
|
882
|
}
|
883
|
|
884
|
private function makeSuperQuery($queries,$sel,$type){
|
885
|
$superquerySelects = "SELECT ";
|
886
|
$superquerySelecte = " ";
|
887
|
$superqueryFrom = " FROM ";
|
888
|
$superquerySort = "";
|
889
|
//ta pedia tou xaxis kai tou group tha einai ayta tou outer join
|
890
|
//sta select yparxei prwta to xaxis, meta i lista me ta fields onomatismena, kai meta an yparxei to group
|
891
|
//sto megalo select tha yparxei gia kathe query to xaxis, meta ola ta fields twn queries me ti seira pou einai sto sel
|
892
|
//kai meta gia kathe query to group field
|
893
|
|
894
|
//prepei na kseroume kathe pedio tou select se poio query anikei, kai to pedio tou order by
|
895
|
for($q=0;$q<count($queries);$q++){//xaxis
|
896
|
//if($q>0) $superquerySelects .= ", ";
|
897
|
$superquerySelects .= "q".$q.".xfield, ";
|
898
|
if($q>0) $superquerySort .= ", ";
|
899
|
$superquerySort .= "q".$q.".xfield ";
|
900
|
|
901
|
if($sel['group']!='' && $sel['group'] != 'no'){//dimfields
|
902
|
/*if($q>0)*/ $superquerySelecte .= ", ";
|
903
|
$superquerySelecte .= "q".$q.".dimfield ";
|
904
|
$superquerySort .= ", q".$q.".dimfield ";
|
905
|
}
|
906
|
|
907
|
$superqueryFrom .= "(".$queries[$q].") as q".$q;
|
908
|
|
909
|
if($q>0){
|
910
|
$superqueryFrom .= " ON q".($q-1).".xfield = q".$q.".xfield ";
|
911
|
if($sel['group']!='' && $sel['group'] != 'no')
|
912
|
$superqueryFrom .= " AND q".($q-1).".dimfield = q".$q.".dimfield ";
|
913
|
}
|
914
|
|
915
|
if($q<count($queries)-1) {
|
916
|
$superqueryFrom .= " FULL JOIN ";
|
917
|
}
|
918
|
|
919
|
}
|
920
|
for($f=0;$f<count($sel['fields']);$f++){//fields
|
921
|
$superquerySelects .= "q".$sel['fields'][$f]['q'].".field".$sel['fields'][$f]['i'];
|
922
|
if($f<(count($sel['fields'])-1)) $superquerySelects .=", ";
|
923
|
}
|
924
|
if(isset($sel['sort']) && $sel['sort']!='xaxis'){
|
925
|
$ex = explode(".", $sel['sortq']);
|
926
|
$temp = "q".$ex[0].".field".$ex[1];
|
927
|
|
928
|
if($sel['order'] && $sel['order'] == 'd')
|
929
|
$temp.= " DESC, ";
|
930
|
else
|
931
|
$temp .= ", ";
|
932
|
|
933
|
$superquerySort = $temp . $superquerySort;
|
934
|
}
|
935
|
|
936
|
$superquerySort = " ORDER BY ".$superquerySort;
|
937
|
|
938
|
$superQuery = $superquerySelects.$superquerySelecte.$superqueryFrom.$superquerySort." LIMIT ".$sel['size'];
|
939
|
$this->log->info("superquery: ".$superQuery);
|
940
|
$res = $this->doQuery($superQuery, PDO::FETCH_NUM);
|
941
|
return $this->combineData($res,count($queries),count($sel['fields']),$type);
|
942
|
}
|
943
|
|
944
|
private function combineData($data,$queries,$fields,$type){
|
945
|
$newdata = array();
|
946
|
if(count($data[0]) > $queries+$fields)
|
947
|
$dstart = $queries + $fields;
|
948
|
else
|
949
|
$dstart = -1;
|
950
|
$fstart = $queries;
|
951
|
for($d=0;$d<count($data);$d++){
|
952
|
$newdata[$d] = array();
|
953
|
for($i=0;$i<$queries;$i++)
|
954
|
if($data[$d][$i] != null){
|
955
|
$newdata[$d][0] = $data[$d][$i];
|
956
|
break;
|
957
|
}
|
958
|
for($i=$fstart;$i<$fields+$queries;$i++)
|
959
|
$newdata[$d][$i-$fstart+1] = $data[$d][$i];
|
960
|
if($dstart > 0)
|
961
|
for($i=$dstart;$i<count($data[0]);$i++)
|
962
|
if($data[$d][$i] != null){
|
963
|
$newdata[$d][$fields+1] = $data[$d][$i];
|
964
|
break;
|
965
|
}
|
966
|
}
|
967
|
$this->log->info("superquerys result: ".print_r($newdata,true));
|
968
|
return array('type'=>$type,'data'=>$newdata);
|
969
|
}
|
970
|
|
971
|
private function clearselections(&$sel,$seperate,$field,$index){
|
972
|
$newsel = array();
|
973
|
$fields = array();
|
974
|
$newsel['table'] = $sel['table'];
|
975
|
$newsel['xaxis'] = $sel['xaxis'];
|
976
|
$newsel['group'] = $sel['group'];
|
977
|
$newsel['color'] = $sel['color'];
|
978
|
$newsel['size'] = $sel['size'];
|
979
|
$newsel['fields'] = array();
|
980
|
$newsel['filters'] = array();
|
981
|
$newsel['having'] = array();
|
982
|
if($field == -1 || $field == -2){ //things that apply to whole chart, will remove only the things that apply to one field and that field
|
983
|
for($i=0;$i<count($sel['fields']);$i++){
|
984
|
if(!in_array($i+1,$seperate)){
|
985
|
$newsel['fields'][] = $sel['fields'][$i];
|
986
|
$sel['fields'][$i]['q'] = $index;
|
987
|
$sel['fields'][$i]['i'] = count($newsel['fields'])-1;
|
988
|
$fields[] = $sel['fields'][$i]['agg'] + "-" + $sel['fields'][$i]['fld'];
|
989
|
}
|
990
|
}
|
991
|
for($i=0;$i<count($sel['filters']);$i++){
|
992
|
if(!isset($sel['filters'][$i]['to']) || $sel['filters'][$i]['to'] == -1){
|
993
|
$newsel['filters'][] = $sel['filters'][$i];
|
994
|
}
|
995
|
}
|
996
|
for($i=0;$i<count($sel['having']);$i++){
|
997
|
if(!isset($sel['having'][$i]['to']) || $sel['having'][$i]['to'] == -1){
|
998
|
$newsel['having'][] = $sel['having'][$i];
|
999
|
}
|
1000
|
}
|
1001
|
if(in_array($sel['sort'],$fields)){
|
1002
|
$sel['sortq'] = $index.".".(count($newsel['fields'])-1);
|
1003
|
//$newsel['sort'] = $sel['sort'];
|
1004
|
}
|
1005
|
//else
|
1006
|
//$newsel['sort'] = 'xaxis';
|
1007
|
}
|
1008
|
else{ //we keep only the field, and the filters and havings that apply to that and the whole chart
|
1009
|
$newsel['fields'][] = $sel['fields'][$field-1];
|
1010
|
$sel['fields'][$field-1]['q'] = $index;
|
1011
|
$sel['fields'][$field-1]['i'] = count($newsel['fields'])-1;
|
1012
|
for($i=0;$i<count($sel['filters']);$i++){
|
1013
|
if(isset($sel['filters'][$i]['to']) && ($sel['filters'][$i]['to'] == $field || $sel['filters'][$i]['to'] == -1)){
|
1014
|
$newsel['filters'][] = $sel['filters'][$i];
|
1015
|
}
|
1016
|
}
|
1017
|
for($i=0;$i<count($sel['having']);$i++){
|
1018
|
if(isset($sel['having'][$i]['to']) && $sel['having'][$i]['to'] == $field){
|
1019
|
$newsel['having'][] = $sel['having'][$i];
|
1020
|
}
|
1021
|
}
|
1022
|
if(in_array($sel['sort'],$fields)){
|
1023
|
$newsel['sort'] = $sel['sort'];
|
1024
|
}
|
1025
|
else
|
1026
|
$newsel['sort'] = 'xaxis';
|
1027
|
}
|
1028
|
return $newsel;
|
1029
|
}
|
1030
|
|
1031
|
function chartData($sel, $doquery=true){
|
1032
|
if($sel['group']!='' && $sel['group'] != 'no'){ //group
|
1033
|
return $this->chartDataGroup($sel, $doquery);
|
1034
|
}
|
1035
|
else{
|
1036
|
|
1037
|
$this->log->info("sel: ".print_r($sel,true));
|
1038
|
$tree = new QueryTree($sel['table']);
|
1039
|
$tree->updateXAxis($sel['xaxis']['name']);
|
1040
|
$tree->updateYAxis($sel['fields']);
|
1041
|
$tree->updateFilters($sel['filters']);
|
1042
|
if (isset($sel['sort'])) {
|
1043
|
$tree->updateOrderBy($sel['sort']);
|
1044
|
$tree->updateOrder($sel['order']);
|
1045
|
}
|
1046
|
$tree->updateLimit($sel['size']);
|
1047
|
$tree->excludeNulls($sel['nulls']);
|
1048
|
|
1049
|
$this->log->info("tree: ".print_r($tree->tree, true));
|
1050
|
|
1051
|
$query = $tree->getQuery();
|
1052
|
|
1053
|
if(!$doquery){
|
1054
|
$this->log->info('chartData generated query:'.$query);
|
1055
|
$this->log->info('will not execute it');
|
1056
|
return $query;
|
1057
|
}
|
1058
|
|
1059
|
$this->log->info('chartData generated tree: '.print_r($tree->getTree(), true));
|
1060
|
$this->log->info('chartData generated query: '.$query);
|
1061
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1062
|
$this->log->info("result: ".print_r($res,true));
|
1063
|
return array('type'=>'chart','data'=>$res);
|
1064
|
}
|
1065
|
|
1066
|
}
|
1067
|
|
1068
|
function chartDataGroup($sel, $doquery=true){
|
1069
|
//exoume dyo dims, ena tou xaxis kai ena tou group
|
1070
|
//kanoume tin idia diadikasia kai gia ta dyo
|
1071
|
$xfield = '';
|
1072
|
$dimfield = '';
|
1073
|
$tables = array();
|
1074
|
$tablePairs = array();
|
1075
|
$filters = array();
|
1076
|
//order by it
|
1077
|
//may need to join
|
1078
|
//gia to xaxis
|
1079
|
$dimlist = explode("-",$sel['xaxis']['name']);
|
1080
|
if(count($dimlist) == 1){ //einai dim alla den analyetai se pinaka
|
1081
|
$xfield = '"'.$sel['table'].'"."'.$dimlist[count($dimlist)-1].'"';
|
1082
|
}
|
1083
|
else{
|
1084
|
$xfield = '"'.$dimlist[count($dimlist)-2].'"."'.$dimlist[count($dimlist)-1].'"';
|
1085
|
//briskw tous pinakes enan enan kai tous bazw sta pairs
|
1086
|
for($i=0;$i<count($dimlist)-1;$i++){
|
1087
|
if(!in_array($dimlist[$i],$tables)){
|
1088
|
$tables[] = $dimlist[$i];
|
1089
|
}
|
1090
|
if($i == 0){
|
1091
|
if(!in_array_r(array($sel['table'],$dimlist[$i]), $tablePairs)){
|
1092
|
$tablePairs[] = array($sel['table'],$dimlist[$i]);
|
1093
|
}
|
1094
|
}
|
1095
|
else{
|
1096
|
if(!in_array_r(array($dimlist[$i-1],$dimlist[$i]),$tablePairs))
|
1097
|
$tablePairs[] = array($dimlist[$i-1],$dimlist[$i]);
|
1098
|
}
|
1099
|
}
|
1100
|
}
|
1101
|
//gia to group
|
1102
|
$dimlist = explode("-",$sel['group']);
|
1103
|
if(count($dimlist) == 1){ //einai dim alla den analyetai se pinaka
|
1104
|
$dimfield = '"'.$sel['table'].'"."'.$dimlist[count($dimlist)-1].'"';
|
1105
|
}
|
1106
|
else{
|
1107
|
$dimfield = '"'.$dimlist[count($dimlist)-2].'"."'.$dimlist[count($dimlist)-1].'"';
|
1108
|
//briskw tous pinakes enan enan kai tous bazw sta pairs
|
1109
|
for($i=0;$i<count($dimlist)-1;$i++){
|
1110
|
if(!in_array($dimlist[$i],$tables)){
|
1111
|
$tables[] = $dimlist[$i];
|
1112
|
}
|
1113
|
if($i == 0){
|
1114
|
if(!in_array_r(array($sel['table'],$dimlist[$i]), $tablePairs)){
|
1115
|
$tablePairs[] = array($sel['table'],$dimlist[$i]);
|
1116
|
}
|
1117
|
}
|
1118
|
else{
|
1119
|
if(!in_array_r(array($dimlist[$i-1],$dimlist[$i]),$tablePairs))
|
1120
|
$tablePairs[] = array($dimlist[$i-1],$dimlist[$i]);
|
1121
|
}
|
1122
|
}
|
1123
|
}
|
1124
|
//filters
|
1125
|
if(isset($sel['filters'])){
|
1126
|
for($fc=0;$fc<count($sel['filters']);$fc++){
|
1127
|
$filterfields = explode("-",$sel['filters'][$fc]['name']);
|
1128
|
if(count($filterfields)>1){ //join needed
|
1129
|
$sel['filters'][$fc]['name'] = '"'.$filterfields[count($filterfields)-2].'"."'.$filterfields[count($filterfields)-1].'"';
|
1130
|
for($i=0;$i<count($filterfields)-1;$i++){
|
1131
|
if(!in_array($filterfields[$i],$tables)){
|
1132
|
$tables[] = $filterfields[$i];
|
1133
|
}
|
1134
|
if($i == 0){
|
1135
|
if(!in_array_r(array($sel['table'],$filterfields[$i]), $tablePairs)){
|
1136
|
$tablePairs[] = array($sel['table'],$filterfields[$i]);
|
1137
|
}
|
1138
|
}
|
1139
|
else{
|
1140
|
if(!in_array_r(array($filterfields[$i-1],$filterfields[$i]),$tablePairs)){
|
1141
|
$tablePairs[] = array($filterfields[$i-1],$filterfields[$i]);
|
1142
|
}
|
1143
|
}
|
1144
|
}
|
1145
|
}
|
1146
|
else
|
1147
|
$sel['filters'][$fc]['name'] = $sel['table'].".".$sel['filters'][$fc]['name'];
|
1148
|
}
|
1149
|
}
|
1150
|
//----------------------------------------------------------------//
|
1151
|
//having
|
1152
|
if(isset($sel['having'])){
|
1153
|
for($fc=0;$fc<count($sel['having']);$fc++){
|
1154
|
$havingfields = explode("-",$sel['having'][$fc]['name']);
|
1155
|
if(count($havingfields)>1){ //join needed
|
1156
|
$sel['having'][$fc]['name'] = '"'.$havingfields[count($havingfields)-2].'"."'.$havingfields[count($havingfields)-1].'"';
|
1157
|
for($i=0;$i<count($havingfields)-1;$i++){
|
1158
|
if(!in_array($havingfields[$i],$tables)){
|
1159
|
$tables[] = $havingfields[$i];
|
1160
|
}
|
1161
|
if($i == 0){
|
1162
|
if(!in_array_r(array($sel['table'],$havingfields[$i]), $tablePairs)){
|
1163
|
$tablePairs[] = array($sel['table'],$havingfields[$i]);
|
1164
|
}
|
1165
|
}
|
1166
|
else{
|
1167
|
if(!in_array_r(array($havingfields[$i-1],$havingfields[$i]),$tablePairs)){
|
1168
|
$tablePairs[] = array($havingfields[$i-1],$havingfields[$i]);
|
1169
|
}
|
1170
|
}
|
1171
|
}
|
1172
|
}
|
1173
|
}
|
1174
|
}
|
1175
|
//----------------------------------------------------------------//
|
1176
|
$query = 'SELECT '.$xfield.' as xfield';
|
1177
|
for($i=0;$i<count($sel['fields']);$i++){
|
1178
|
$query .= ', '.$sel['fields'][$i]['agg'].'("'.$sel['table'].'"."'.$sel['fields'][$i]['fld'].'") as field'.$i;
|
1179
|
}
|
1180
|
$query .= ', '.$dimfield.' as dimfield';
|
1181
|
$query .= ' FROM "'.$sel['table'].'"';
|
1182
|
if(count($tables)>0) $query .= ', "'.implode("\", \"",$tables).'" ';
|
1183
|
/*$query .= ' WHERE "'.$sel['xaxis']['name'].'" !=""';
|
1184
|
for($i=0;$i<count($sel['fields']);$i++){
|
1185
|
$query .=" and ";
|
1186
|
$query .= '"'.$sel['fields'][$i]['fld'] .'" !=""';
|
1187
|
}*/
|
1188
|
if(count($tablePairs) > 0 || (isset($sel['filters']) && count($sel['filters']) > 0) || $sel['nulls']){
|
1189
|
$query .= " WHERE ";
|
1190
|
for($i=0;$i<count($tablePairs);$i++){
|
1191
|
$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1192
|
if($i!=count($tablePairs)-1) $query .= " and ";
|
1193
|
else $query .= " ";
|
1194
|
}
|
1195
|
//filters
|
1196
|
if(isset($sel['filters']) && count($sel['filters'])>0){
|
1197
|
if(count($tablePairs)>0)
|
1198
|
$query .= " and ";
|
1199
|
for($i=0;$i<count($sel['filters']);$i++){
|
1200
|
if(isset($sel['filters'][$i]['max'])){
|
1201
|
if(strstr($sel['filters'][$i]['name'],"year") !== false && $sel['filters'][$i]['max']=='today')
|
1202
|
$query .= "(".$sel['filters'][$i]['name']."<= extract(YEAR from now()) and ".$sel['filters'][$i]['name'].">=".$sel['filters'][$i]['min'].")";
|
1203
|
else if(strstr($sel['filters'][$i]['name'],"year") !== false && $sel['filters'][$i]['min']=='today')
|
1204
|
$query .="(".$sel['filters'][$i]['name']."<=".$sel['filters'][$i]['max']." and ".$sel['filters'][$i]['name'].">= extract(YEAR from now()))" ;
|
1205
|
else
|
1206
|
$query .= "(".$sel['filters'][$i]['name']."<=".$sel['filters'][$i]['max']." and ".$sel['filters'][$i]['name'].">=".$sel['filters'][$i]['min'].")" ;
|
1207
|
}
|
1208
|
else if(isset($sel['filters'][$i]['values'])){
|
1209
|
$query .= "(";
|
1210
|
for($j=0;$j<count($sel['filters'][$i]['values']);$j++){
|
1211
|
//$query .= $sel['filters'][$i]['name'].'="'.$sel['filters'][$i]['values'][$j].'"';
|
1212
|
$query .= $sel['filters'][$i]['name'].'=\''.$sel['filters'][$i]['values'][$j].'\'';
|
1213
|
if($j!=count($sel['filters'][$i]['values'])-1) $query .= " or ";
|
1214
|
}
|
1215
|
$query .= ")";
|
1216
|
}
|
1217
|
else if(isset($sel['filters'][$i]['exvalues'])){
|
1218
|
$query .= "(";
|
1219
|
for($j=0;$j<count($sel['filters'][$i]['exvalues']);$j++){
|
1220
|
$query .= $sel['filters'][$i]['name'].'!=\''.$sel['filters'][$i]['exvalues'][$j].'\'';
|
1221
|
if($j!=count($sel['filters'][$i]['exvalues'])-1) $query .= " and ";
|
1222
|
}
|
1223
|
$query .= ")";
|
1224
|
}
|
1225
|
//$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1226
|
if($i!=count($sel['filters'])-1) $query .= " and ";
|
1227
|
else $query .= " ";
|
1228
|
}
|
1229
|
}
|
1230
|
if($sel['nulls'] == true){//non null values from xaxis field and dimfield
|
1231
|
if((isset($sel['filters']) && count($sel['filters'])>0) || count($tablePairs) > 0){
|
1232
|
$query .= " and ";
|
1233
|
}
|
1234
|
$query .= $xfield . " IS NOT NULL AND ". $dimfield . " IS NOT NULL ";
|
1235
|
}
|
1236
|
}
|
1237
|
//--------------------------------------------------------//
|
1238
|
$query .= " GROUP BY ".$dimfield.', '.$xfield;
|
1239
|
if(count($sel['having'])>0){
|
1240
|
$query .= " HAVING ";
|
1241
|
for($i=0;$i<count($sel['having']);$i++){
|
1242
|
if($i>0)
|
1243
|
$query .= " and ";
|
1244
|
$query .= $sel['having'][$i]['agg']."(".$sel['having'][$i]['name'].")".$sel['having'][$i]['fnc'].$sel['having'][$i]['value'];
|
1245
|
}
|
1246
|
|
1247
|
}
|
1248
|
|
1249
|
if(!$doquery){
|
1250
|
$this->log->info('chartDataGroup generated query:'.$query);
|
1251
|
$this->log->info('will not execute it');
|
1252
|
return $query;
|
1253
|
}
|
1254
|
|
1255
|
//need to find the field to order the result set by
|
1256
|
$query.= " ORDER BY ";
|
1257
|
if(isset($sel['sort']) && $sel['sort']!='xaxis'){
|
1258
|
$ex = explode("-", $sel['sort']);
|
1259
|
$query .= $ex[0]."(".$sel['table'].".".$ex[1].")";
|
1260
|
if($sel['order'] && $sel['order'] == 'd')
|
1261
|
$query.= " DESC";
|
1262
|
$query .= ", ".$xfield;
|
1263
|
}
|
1264
|
else{
|
1265
|
$query.= $xfield;
|
1266
|
if($sel['order'] && $sel['order'] == 'd')
|
1267
|
$query.= " DESC";
|
1268
|
}
|
1269
|
$query.=', '.$dimfield;
|
1270
|
$query.= " LIMIT ".$sel['size'];
|
1271
|
//echo $query;
|
1272
|
$this->log->info('chartDataGroup generated query:'.$query);
|
1273
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1274
|
$this->log->info("result: ".print_r($res,true));
|
1275
|
return array('type'=>'chart','data'=>$res);
|
1276
|
|
1277
|
}
|
1278
|
|
1279
|
function scatterData($sel, $doquery=true){
|
1280
|
//group, color, or nothing
|
1281
|
//many fields or one
|
1282
|
if($sel['group']!='' && $sel['group'] != 'no'){ //group
|
1283
|
$this->log->info('scatterDataGroup called');
|
1284
|
return $this->scatterDataGroup($sel, $doquery);
|
1285
|
}
|
1286
|
else if($sel['color']!='' && $sel['color'] != 'no'){ //color
|
1287
|
$this->log->info('scatterDataColor called');
|
1288
|
return $this->scatterDataColor($sel, $doquery);
|
1289
|
}
|
1290
|
else{ //nothing
|
1291
|
$this->log->info('scatterData called');
|
1292
|
//code here
|
1293
|
//no dim to bother us, just the measurements
|
1294
|
//TODO: get all other dims to show in tooltip
|
1295
|
$tables = array();
|
1296
|
$tablePairs = array();
|
1297
|
$filters = array();
|
1298
|
//filters
|
1299
|
if(isset($sel['filters'])){
|
1300
|
for($fc=0;$fc<count($sel['filters']);$fc++){
|
1301
|
$filterfields = explode("-",$sel['filters'][$fc]['name']);
|
1302
|
if(count($filterfields)==1){ //no join needed
|
1303
|
;//$filters[] = $sel['filters'][$fc];
|
1304
|
$sel['filters'][$fc]['name'] = $sel['table'].".".$sel['filters'][$fc]['name'];
|
1305
|
}
|
1306
|
else{
|
1307
|
$sel['filters'][$fc]['name'] = '"'.$filterfields[count($filterfields)-2].'"."'.$filterfields[count($filterfields)-1].'"';
|
1308
|
for($i=0;$i<count($filterfields)-1;$i++){
|
1309
|
if(!in_array($filterfields[$i],$tables)){
|
1310
|
$tables[] = $filterfields[$i];
|
1311
|
}
|
1312
|
if($i == 0){
|
1313
|
if(!in_array_r(array($sel['table'],$filterfields[$i]), $tablePairs)){
|
1314
|
$tablePairs[] = array($sel['table'],$filterfields[$i]);
|
1315
|
}
|
1316
|
}
|
1317
|
else{
|
1318
|
if(!in_array_r(array($filterfields[$i-1],$filterfields[$i]),$tablePairs)){
|
1319
|
$tablePairs[] = array($filterfields[$i-1],$filterfields[$i]);
|
1320
|
}
|
1321
|
}
|
1322
|
}
|
1323
|
}
|
1324
|
}
|
1325
|
}
|
1326
|
//----------------------------------------------------------------//
|
1327
|
//having
|
1328
|
if(isset($sel['having'])){
|
1329
|
for($fc=0;$fc<count($sel['having']);$fc++){
|
1330
|
$havingfields = explode("-",$sel['having'][$fc]['name']);
|
1331
|
if(count($havingfields)>1){ //join needed
|
1332
|
$sel['having'][$fc]['name'] = '"'.$havingfields[count($havingfields)-2].'"."'.$havingfields[count($havingfields)-1].'"';
|
1333
|
for($i=0;$i<count($havingfields)-1;$i++){
|
1334
|
if(!in_array($havingfields[$i],$tables)){
|
1335
|
$tables[] = $havingfields[$i];
|
1336
|
}
|
1337
|
if($i == 0){
|
1338
|
if(!in_array_r(array($sel['table'],$havingfields[$i]), $tablePairs)){
|
1339
|
$tablePairs[] = array($sel['table'],$havingfields[$i]);
|
1340
|
}
|
1341
|
}
|
1342
|
else{
|
1343
|
if(!in_array_r(array($havingfields[$i-1],$havingfields[$i]),$tablePairs)){
|
1344
|
$tablePairs[] = array($havingfields[$i-1],$havingfields[$i]);
|
1345
|
}
|
1346
|
}
|
1347
|
}
|
1348
|
}
|
1349
|
}
|
1350
|
}
|
1351
|
//----------------------------------------------------------------//
|
1352
|
$query = 'SELECT "'.$sel['table'].'"."'.$sel['xaxis']['name'].' " as xfield';
|
1353
|
for($i=0;$i<count($sel['fields']);$i++){
|
1354
|
$query .= ', "'.$sel['table'].'"."'.$sel['fields'][$i]['fld'].'" as field'.$i;
|
1355
|
}
|
1356
|
$query .= ' FROM "'.$sel['table'].'"';
|
1357
|
if(count($tables)>0) $query .= ', "'.implode("\", \"",$tables).'" ';
|
1358
|
|
1359
|
$query .= ' WHERE ';
|
1360
|
for($i=0;$i<count($sel['fields']);$i++){
|
1361
|
if($i>0) $query .=" AND ";
|
1362
|
$query .= "field".$i.'" IS NOT NULL';
|
1363
|
}
|
1364
|
//joins + filters
|
1365
|
if(count($tablePairs) > 0 || (isset($sel['filters']) && count($sel['filters']) > 0) || $sel['nulls']){
|
1366
|
$query .= " AND ";
|
1367
|
for($i=0;$i<count($tablePairs);$i++){
|
1368
|
$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1369
|
if($i!=count($tablePairs)-1) $query .= " and ";
|
1370
|
else $query .= " ";
|
1371
|
}
|
1372
|
if(isset($sel['filters']) && count($sel['filters'])>0){
|
1373
|
if(count($tablePairs)>0) $query .= " and ";
|
1374
|
for($i=0;$i<count($sel['filters']);$i++){
|
1375
|
if(isset($sel['filters'][$i]['max'])){
|
1376
|
$query .= "(".$sel['filters'][$i]['name']."<=".$sel['filters'][$i]['max']." and ".$sel['filters'][$i]['name'].">=".$sel['filters'][$i]['min'].")" ;
|
1377
|
}
|
1378
|
else{
|
1379
|
$query .= "(";
|
1380
|
for($j=0;$j<count($sel['filters'][$i]['values']);$j++){
|
1381
|
$query .= $sel['filters'][$i]['name'].'="'.$sel['filters'][$i]['values'][$j].'"';
|
1382
|
if($j!=count($sel['filters'][$i]['values'])-1) $query .= " or ";
|
1383
|
}
|
1384
|
$query .= ")";
|
1385
|
}
|
1386
|
//$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1387
|
if($i!=count($sel['filters'])-1) $query .= " and ";
|
1388
|
else $query .= " ";
|
1389
|
}
|
1390
|
}
|
1391
|
if($sel['nulls'] == true){//non null values from xaxis field and dimfield
|
1392
|
if((isset($sel['filters']) && count($sel['filters'])>0) || count($tablePairs) > 0){
|
1393
|
$query .= " and ";
|
1394
|
}
|
1395
|
$query .= $xfield . " IS NOT NULL ";
|
1396
|
}
|
1397
|
}
|
1398
|
if(count($sel['having'])>0){
|
1399
|
$query .= " HAVING ";
|
1400
|
for($i=0;$i<count($sel['having']);$i++){
|
1401
|
if($i>0)
|
1402
|
$query .= " and ";
|
1403
|
$query .= $sel['having'][$i]['agg']."(".$sel['having'][$i]['name'].")".$sel['having'][$i]['fnc'].$sel['having'][$i]['value'];
|
1404
|
}
|
1405
|
|
1406
|
}
|
1407
|
//--------------------------------------------------------//
|
1408
|
|
1409
|
if(!$doquery){
|
1410
|
$this->log->info('scatterData generated query:'.$query);
|
1411
|
$this->log->info('will not execute it');
|
1412
|
return $query;
|
1413
|
}
|
1414
|
$this->log->info('scatterData generated query:'.$query);
|
1415
|
//echo "scatterplot, simple case:"; echo $query;
|
1416
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1417
|
|
1418
|
$this->log->info("result: ".print_r($res,true));
|
1419
|
return array('type'=>'scatter','data'=>$res);
|
1420
|
}
|
1421
|
}
|
1422
|
|
1423
|
function scatterDataColor($sel, $doquery=true){
|
1424
|
//one dim, the one for the color
|
1425
|
//TODO: get all other dims to show in tooltip
|
1426
|
$dimfield = '';
|
1427
|
$tables = array();
|
1428
|
$tablePairs = array();
|
1429
|
//order by it
|
1430
|
//may need to join
|
1431
|
$dimlist = explode("-",$sel['color']);
|
1432
|
if(count($dimlist) == 1){ //einai dim alla den analyetai se pinaka
|
1433
|
$dimfield = '"'.$sel['table'].'"."'.$dimlist[count($dimlist)-1].'"';
|
1434
|
}
|
1435
|
else{
|
1436
|
$dimfield = '"'.$dimlist[count($dimlist)-2].'"."'.$dimlist[count($dimlist)-1].'"';
|
1437
|
//briskw tous pinakes enan enan kai tous bazw sta pairs
|
1438
|
for($i=0;$i<count($dimlist)-1;$i++){
|
1439
|
if(!in_array($dimlist[$i],$tables)){
|
1440
|
$tables[] = $dimlist[$i];
|
1441
|
}
|
1442
|
if($i == count($dimlist)-2){
|
1443
|
if(!in_array_r(array($sel['table'],$dimlist[$i]), $tablePairs)){
|
1444
|
$tablePairs[] = array($sel['table'],$dimlist[$i]);
|
1445
|
}
|
1446
|
}
|
1447
|
else{
|
1448
|
if(!in_array_r(array($dimlist[$i],$dimlist[$i+1]),$tablePairs))
|
1449
|
$tablePairs[] = array($dimlist[$i],$dimlist[$i+1]);
|
1450
|
}
|
1451
|
}
|
1452
|
}
|
1453
|
//filters
|
1454
|
if(isset($sel['filters'])){
|
1455
|
for($fc=0;$fc<count($sel['filters']);$fc++){
|
1456
|
$filterfields = explode("-",$sel['filters'][$fc]['name']);
|
1457
|
if(count($filterfields)==1){ //no join needed
|
1458
|
;//$filters[] = $sel['filters'][$fc];
|
1459
|
}
|
1460
|
else{
|
1461
|
$sel['filters'][$fc]['name'] = '"'.$filterfields[count($filterfields)-2].'"."'.$filterfields[count($filterfields)-1].'"';
|
1462
|
for($i=0;$i<count($filterfields)-1;$i++){
|
1463
|
if(!in_array($filterfields[$i],$tables)){
|
1464
|
$tables[] = $filterfields[$i];
|
1465
|
}
|
1466
|
if($i == 0){
|
1467
|
if(!in_array_r(array($sel['table'],$filterfields[$i]), $tablePairs)){
|
1468
|
$tablePairs[] = array($sel['table'],$filterfields[$i]);
|
1469
|
}
|
1470
|
}
|
1471
|
else{
|
1472
|
if(!in_array_r(array($filterfields[$i-1],$filterfields[$i]),$tablePairs)){
|
1473
|
$tablePairs[] = array($filterfields[$i-1],$filterfields[$i]);
|
1474
|
}
|
1475
|
}
|
1476
|
}
|
1477
|
}
|
1478
|
}
|
1479
|
}
|
1480
|
//----------------------------------------------------------------//
|
1481
|
//having
|
1482
|
if(isset($sel['having'])){
|
1483
|
for($fc=0;$fc<count($sel['having']);$fc++){
|
1484
|
$havingfields = explode("-",$sel['having'][$fc]['name']);
|
1485
|
if(count($havingfields)>1){ //join needed
|
1486
|
$sel['having'][$fc]['name'] = '"'.$havingfields[count($havingfields)-2].'"."'.$havingfields[count($havingfields)-1].'"';
|
1487
|
for($i=0;$i<count($havingfields)-1;$i++){
|
1488
|
if(!in_array($havingfields[$i],$tables)){
|
1489
|
$tables[] = $havingfields[$i];
|
1490
|
}
|
1491
|
if($i == 0){
|
1492
|
if(!in_array_r(array($sel['table'],$havingfields[$i]), $tablePairs)){
|
1493
|
$tablePairs[] = array($sel['table'],$havingfields[$i]);
|
1494
|
}
|
1495
|
}
|
1496
|
else{
|
1497
|
if(!in_array_r(array($havingfields[$i-1],$havingfields[$i]),$tablePairs)){
|
1498
|
$tablePairs[] = array($havingfields[$i-1],$havingfields[$i]);
|
1499
|
}
|
1500
|
}
|
1501
|
}
|
1502
|
}
|
1503
|
}
|
1504
|
}
|
1505
|
//----------------------------------------------------------------//
|
1506
|
$query = 'SELECT "'.$sel['table'].'"."'.$sel['xaxis']['name'].'" as xfield';
|
1507
|
for($i=0;$i<count($sel['fields']);$i++){
|
1508
|
$query .= ', "'.$sel['table'].'"."'.$sel['fields'][$i]['fld'].'" as field'.$i;
|
1509
|
}
|
1510
|
$query .= ', '.$dimfield.' as dimfield';
|
1511
|
$query .= ' FROM "'.$sel['table'].'"';
|
1512
|
if(count($tables)>0) $query .= ', "'.implode("\", \"",$tables).'" ';
|
1513
|
|
1514
|
$query .= " WHERE ";
|
1515
|
for($i=0;$i<count($sel['fields']);$i++){
|
1516
|
if($i>0) $query .=" AND ";
|
1517
|
$query .= "field".$i.'" IS NOT NULL';
|
1518
|
}
|
1519
|
if(count($tablePairs) > 0){
|
1520
|
$query .= " AND ";
|
1521
|
for($i=0;$i<count($tablePairs);$i++){
|
1522
|
$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1523
|
if($i!=count($tablePairs)-1) $query .= "AND ";
|
1524
|
else $query .= " ";
|
1525
|
}
|
1526
|
}
|
1527
|
//filters
|
1528
|
if(isset($sel['filters']) && count($sel['filters'])>0){
|
1529
|
if(count($tablePairs)>0) $query .= " AND ";
|
1530
|
for($i=0;$i<count($sel['filters']);$i++){
|
1531
|
if(isset($sel['filters'][$i]['max'])){
|
1532
|
$query .= "(".$sel['filters'][$i]['name']."<=".$sel['filters'][$i]['max']." AND ".$sel['filters'][$i]['name'].">=".$sel['filters'][$i]['min'].")" ;
|
1533
|
}
|
1534
|
else{
|
1535
|
$query .= "(";
|
1536
|
for($j=0;$j<count($sel['filters'][$i]['values']);$j++){
|
1537
|
$query .= $sel['filters'][$i]['name'].'="'.$sel['filters'][$i]['values'][$j].'"';
|
1538
|
if($j!=count($sel['filters'][$i]['values'])-1) $query .= " or ";
|
1539
|
}
|
1540
|
$query .= ")";
|
1541
|
}
|
1542
|
//$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1543
|
if($i!=count($sel['filters'])-1) $query .= " AND ";
|
1544
|
else $query .= " ";
|
1545
|
}
|
1546
|
}
|
1547
|
if(count($sel['having'])>0){
|
1548
|
$query .= " HAVING ";
|
1549
|
for($i=0;$i<count($sel['having']);$i++){
|
1550
|
if($i>0)
|
1551
|
$query .= " and ";
|
1552
|
$query .= $sel['having'][$i]['agg']."(".$sel['having'][$i]['name'].")".$sel['having'][$i]['fnc'].$sel['having'][$i]['value'];
|
1553
|
}
|
1554
|
|
1555
|
}
|
1556
|
|
1557
|
if(!$doquery){
|
1558
|
$this->log->info('chartDataColor generated query:'.$query);
|
1559
|
$this->log->info('will not execute it');
|
1560
|
return $query;
|
1561
|
}
|
1562
|
|
1563
|
//--------------------------------------------------------//
|
1564
|
$query .= " ORDER BY ".$dimfield;
|
1565
|
//echo "scatterplot, case color:"; echo $query;
|
1566
|
$this->log->info('scatterDataColor generated query:'.$query);
|
1567
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1568
|
|
1569
|
$this->log->info("result: ".print_r($res,true));
|
1570
|
return array('type'=>'scatter','data'=>$res);
|
1571
|
}
|
1572
|
|
1573
|
function scatterDataGroup($sel, $doquery=true){
|
1574
|
//one dim, the one for the group
|
1575
|
//aggrs for all fields
|
1576
|
//TODO: get all other dims to show in tooltip
|
1577
|
$dimfield = '';
|
1578
|
$tables = array();
|
1579
|
$tablePairs = array();
|
1580
|
//order by it
|
1581
|
//may need to join
|
1582
|
$dimlist = explode("-",$sel['group']);
|
1583
|
if(count($dimlist) == 1){ //einai dim alla den analyetai se pinaka
|
1584
|
$dimfield = '"'.$sel['table'].'"."'.$dimlist[count($dimlist)-1].'"';
|
1585
|
}
|
1586
|
else{
|
1587
|
$dimfield = '"'.$dimlist[count($dimlist)-2].'"."'.$dimlist[count($dimlist)-1].'"';
|
1588
|
//briskw tous pinakes enan enan kai tous bazw sta pairs
|
1589
|
for($i=0;$i<count($dimlist)-1;$i++){
|
1590
|
if(!in_array($dimlist[$i],$tables)){
|
1591
|
$tables[] = $dimlist[$i];
|
1592
|
}
|
1593
|
if($i == count($dimlist)-2){
|
1594
|
if(!in_array_r(array($sel['table'],$dimlist[$i]), $tablePairs)){
|
1595
|
$tablePairs[] = array($sel['table'],$dimlist[$i]);
|
1596
|
}
|
1597
|
}
|
1598
|
else{
|
1599
|
if(!in_array_r(array($dimlist[$i],$dimlist[$i+1]),$tablePairs))
|
1600
|
$tablePairs[] = array($dimlist[$i],$dimlist[$i+1]);
|
1601
|
}
|
1602
|
}
|
1603
|
}
|
1604
|
//filters
|
1605
|
if(isset($sel['filters'])){
|
1606
|
for($fc=0;$fc<count($sel['filters']);$fc++){
|
1607
|
$filterfields = explode("-",$sel['filters'][$fc]['name']);
|
1608
|
if(count($filterfields)>1){ //join needed
|
1609
|
$sel['filters'][$fc]['name'] = '"'.$filterfields[count($filterfields)-2].'"."'.$filterfields[count($filterfields)-1].'"';
|
1610
|
for($i=0;$i<count($filterfields)-1;$i++){
|
1611
|
if(!in_array($filterfields[$i],$tables)){
|
1612
|
$tables[] = $filterfields[$i];
|
1613
|
}
|
1614
|
if($i == 0){
|
1615
|
if(!in_array_r(array($sel['table'],$filterfields[$i]), $tablePairs)){
|
1616
|
$tablePairs[] = array($sel['table'],$filterfields[$i]);
|
1617
|
}
|
1618
|
}
|
1619
|
else{
|
1620
|
if(!in_array_r(array($filterfields[$i-1],$filterfields[$i]),$tablePairs)){
|
1621
|
$tablePairs[] = array($filterfields[$i-1],$filterfields[$i]);
|
1622
|
}
|
1623
|
}
|
1624
|
}
|
1625
|
}
|
1626
|
}
|
1627
|
}
|
1628
|
//----------------------------------------------------------------//
|
1629
|
//having
|
1630
|
if(isset($sel['having'])){
|
1631
|
for($fc=0;$fc<count($sel['having']);$fc++){
|
1632
|
$havingfields = explode("-",$sel['having'][$fc]['name']);
|
1633
|
if(count($havingfields)>1){ //join needed
|
1634
|
$sel['having'][$fc]['name'] = '"'.$havingfields[count($havingfields)-2].'"."'.$havingfields[count($havingfields)-1].'"';
|
1635
|
for($i=0;$i<count($havingfields)-1;$i++){
|
1636
|
if(!in_array($havingfields[$i],$tables)){
|
1637
|
$tables[] = $havingfields[$i];
|
1638
|
}
|
1639
|
if($i == 0){
|
1640
|
if(!in_array_r(array($sel['table'],$havingfields[$i]), $tablePairs)){
|
1641
|
$tablePairs[] = array($sel['table'],$havingfields[$i]);
|
1642
|
}
|
1643
|
}
|
1644
|
else{
|
1645
|
if(!in_array_r(array($havingfields[$i-1],$havingfields[$i]),$tablePairs)){
|
1646
|
$tablePairs[] = array($havingfields[$i-1],$havingfields[$i]);
|
1647
|
}
|
1648
|
}
|
1649
|
}
|
1650
|
}
|
1651
|
}
|
1652
|
}
|
1653
|
//----------------------------------------------------------------//
|
1654
|
$query = 'SELECT '.$sel['xaxis']['agg'].'("'.$sel['table'].'"."'.$sel['xaxis']['name'].'") as xfield';
|
1655
|
for($i=0;$i<count($sel['fields']);$i++){
|
1656
|
$query .= ', '.$sel['fields'][$i]['agg'].'("'.$sel['table'].'"."'.$sel['fields'][$i]['fld'].'")';
|
1657
|
}
|
1658
|
$query .= ' ,'.$dimfield.' as dimfield';
|
1659
|
$query .= ' FROM "'.$sel['table'].'"';
|
1660
|
if(count($tables)>0) $query .= ', "'.implode("\", \"",$tables).'" ';
|
1661
|
|
1662
|
$query .= ' WHERE ';
|
1663
|
for($i=0;$i<count($sel['fields']);$i++){
|
1664
|
if($i>0) $query .=" AND ";
|
1665
|
$query .= 'field'.$i." IS NOT NULL";
|
1666
|
}
|
1667
|
|
1668
|
if(count($tablePairs) > 0){
|
1669
|
$query .= " AND ";
|
1670
|
for($i=0;$i<count($tablePairs);$i++){
|
1671
|
$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1672
|
if($i!=count($tablePairs)-1) $query .= "AND ";
|
1673
|
else $query .= " ";
|
1674
|
}
|
1675
|
}
|
1676
|
//filters
|
1677
|
if(isset($sel['filters']) && count($sel['filters'])>0){
|
1678
|
$query .= " AND ";
|
1679
|
for($i=0;$i<count($sel['filters']);$i++){
|
1680
|
if(isset($sel['filters'][$i]['max'])){
|
1681
|
$query .= "(".$sel['filters'][$i]['name']."<=".$sel['filters'][$i]['max']." AND ".$sel['filters'][$i]['name'].">=".$sel['filters'][$i]['min'].")" ;
|
1682
|
}
|
1683
|
else{
|
1684
|
$query .= "(";
|
1685
|
for($j=0;$j<count($sel['filters'][$i]['values']);$j++){
|
1686
|
$query .= $sel['filters'][$i]['name'].'="'.$sel['filters'][$i]['values'][$j].'"';
|
1687
|
if($j!=count($sel['filters'][$i]['values'])-1) $query .= " or ";
|
1688
|
}
|
1689
|
$query .= ")";
|
1690
|
}
|
1691
|
//$query .= '"'.$tablePairs[$i][0].'"."'.$tablePairs[$i][1].'"="'.$tablePairs[$i][1].'".id';
|
1692
|
if($i!=count($sel['filters'])-1) $query .= " AND ";
|
1693
|
else $query .= " ";
|
1694
|
}
|
1695
|
}
|
1696
|
//--------------------------------------------------------//
|
1697
|
$query .= " GROUP BY ".$dimfield;
|
1698
|
if(count($sel['having'])>0){
|
1699
|
$query .= " HAVING ";
|
1700
|
for($i=0;$i<count($sel['having']);$i++){
|
1701
|
if($i>0)
|
1702
|
$query .= " and ";
|
1703
|
$query .= $sel['having'][$i]['agg']."(".$sel['having'][$i]['name'].")".$sel['having'][$i]['fnc'].$sel['having'][$i]['value'];
|
1704
|
}
|
1705
|
|
1706
|
}
|
1707
|
|
1708
|
if(!$doquery){
|
1709
|
$this->log->info('chartDataGroup generated query:'.$query);
|
1710
|
$this->log->info('will not execute it');
|
1711
|
return $query;
|
1712
|
}
|
1713
|
//echo "scatterplot, case group:"; echo $query;
|
1714
|
$this->log->info('scatterDataGroup generated query:'.$query);
|
1715
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1716
|
|
1717
|
$this->log->info("result: ".print_r($res,true));
|
1718
|
return array('type'=>'scatter','data'=>$res);
|
1719
|
}
|
1720
|
|
1721
|
function performQuery($query){
|
1722
|
$this->log->info("perfoming query");
|
1723
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1724
|
|
1725
|
$this->log->info("result: ".print_r($res,true));
|
1726
|
return $res;
|
1727
|
}
|
1728
|
|
1729
|
function makeQuery($selectedData){
|
1730
|
$this->log->info("makeQuery");
|
1731
|
$isMeas = false;
|
1732
|
$hasGroups = true;
|
1733
|
$selectList = array();
|
1734
|
$groupbyList = array();
|
1735
|
$whereList = array();
|
1736
|
$groupby = "";
|
1737
|
$orderby = "";
|
1738
|
$lastSelect = array();
|
1739
|
|
1740
|
$tablesList = array();
|
1741
|
$tablesPairs = array();
|
1742
|
$xaxistables = array();
|
1743
|
$dimsList = array();
|
1744
|
$dimsList = $this->queryAllDims($selectedData['table']);
|
1745
|
//create the tables list and the tables pairs list
|
1746
|
$tablesList[] = $selectedData['table'];
|
1747
|
foreach($selectedData['series'] as $series) {
|
1748
|
$seriesexploded = explode("-",$series);
|
1749
|
if(count($seriesexploded) == 1) {
|
1750
|
$groupbyList[] = '"'.$selectedData['table'].'"."'.$seriesexploded[0].'"';
|
1751
|
$lastSelect[] = $seriesexploded[0];
|
1752
|
}
|
1753
|
else{
|
1754
|
$i=0;
|
1755
|
if(!in_array($seriesexploded[$i],$tablesList))
|
1756
|
$tablesList[] = $seriesexploded[$i];
|
1757
|
|
1758
|
if(!in_array_r(array($selectedData['table'],$seriesexploded[0]),$tablesPairs))
|
1759
|
$tablesPairs[] = array($selectedData['table'],$seriesexploded[0]);
|
1760
|
|
1761
|
for($j=1;$j<count($seriesexploded)-1;$j++) {
|
1762
|
if(!in_array($seriesexploded[$j],$tablesList))
|
1763
|
$tablesList[] = $seriesexploded[$j];
|
1764
|
if(!in_array_r(array($seriesexploded[$i],$seriesexploded[$j]),$tablesPairs))
|
1765
|
$tablesPairs[] = array($seriesexploded[$i],$seriesexploded[$j]);
|
1766
|
$i++;
|
1767
|
}
|
1768
|
$groupbyList[] = '"'.$seriesexploded[count($seriesexploded)-2].'"."'.$seriesexploded[count($seriesexploded)-1].'"';
|
1769
|
$lastSelect[] = $seriesexploded[count($seriesexploded)-1];
|
1770
|
}
|
1771
|
}
|
1772
|
$xaxistables = explode("-",$selectedData['xaxis']['name']);
|
1773
|
if($this->checkMeas($selectedData['table'], $xaxistables[count($xaxistables)-1])){
|
1774
|
$isMeas = true;
|
1775
|
$hasGroups = false;
|
1776
|
}
|
1777
|
if(count($xaxistables) == 1){
|
1778
|
if($isMeas && $selectedData['group'] && $selectedData['group'] != ''){
|
1779
|
if($selectedData['xaxis']['agg'] == 'none')
|
1780
|
$selectList[] = "avg('".$selectedData['table'].'"."'.$xaxistables[0].'")';
|
1781
|
else
|
1782
|
$selectList[] = $selectedData['xaxis']['agg']+'("'.$selectedData['table'].'"."'.$xaxistables[0].'")';
|
1783
|
}
|
1784
|
else{
|
1785
|
$selectList[] = '"'.$selectedData['table'].'"."'.$xaxistables[0].'"';
|
1786
|
}
|
1787
|
if(!$isMeas){
|
1788
|
$groupbyList[] = '"'.$selectedData['table'].'"."'.$xaxistables[0].'"';
|
1789
|
}
|
1790
|
}
|
1791
|
else {
|
1792
|
$selectList[] = '"'.$xaxistables[count($xaxistables)-2].'"."'.$xaxistables[count($xaxistables)-1].'"';
|
1793
|
if(!$isMeas){
|
1794
|
$groupbyList[] = '"'.$xaxistables[count($xaxistables)-2].'"."'.$xaxistables[count($xaxistables)-1].'"';
|
1795
|
}
|
1796
|
if(!in_array($xaxistables[count($xaxistables)-2],$tablesList))
|
1797
|
$tablesList[] = $xaxistables[count($xaxistables)-2];
|
1798
|
|
1799
|
if(!in_array_r(array($selectedData['table'],$xaxistables[0]),$tablesPairs))
|
1800
|
$tablesPairs[] = array($selectedData['table'],$xaxistables[0]);
|
1801
|
for($i=0;$i<count($xaxistables)-2;$i++) {
|
1802
|
if(!in_array($xaxistables[$i],$tablesList))
|
1803
|
$tablesList[] = $xaxistables[$i];
|
1804
|
|
1805
|
if(!in_array_r(array($xaxistables[$i],$xaxistables[$i+1]),$tablesPairs))
|
1806
|
$tablesPairs[] = array($xaxistables[$i],$xaxistables[$i+1]);
|
1807
|
}
|
1808
|
}
|
1809
|
$orderby = implode(", ",$groupbyList);
|
1810
|
$groupby = implode(", ",$groupbyList);
|
1811
|
|
1812
|
foreach($tablesPairs as $pair) {
|
1813
|
$whereList[] = '"'.$pair[0].'"."'.$pair[1].'" = "'.$pair[1].'".id';
|
1814
|
}
|
1815
|
|
1816
|
foreach($selectedData['fields'] as $field) {
|
1817
|
if($hasGroups){
|
1818
|
if($field['agg'] == 'none')
|
1819
|
$selectList[] ='avg("'.$selectedData['table'].'"."'.$field['fld'].'")';
|
1820
|
else
|
1821
|
$selectList[] = $field['agg'].'("'.$selectedData['table'].'"."'.$field['fld'].'")';
|
1822
|
}
|
1823
|
else
|
1824
|
$selectList[] = '"'.$selectedData['table'].'"."'.$field['fld'].'"';
|
1825
|
}
|
1826
|
$query = "select ".implode(", ",$selectList);
|
1827
|
if(count($lastSelect)!=0)
|
1828
|
$query .= ", ".implode(" || '-' || ",$lastSelect)." as seriesName ";
|
1829
|
$query .= " from '".implode("', '",$tablesList)."'";
|
1830
|
$query .= " where ";
|
1831
|
for($i=0;$i<count($selectedData['fields']);$i++) {
|
1832
|
if($i!=0) $query .=" and ";
|
1833
|
$query .= '"'.$selectedData['fields'][$i]['fld'] .'" !=""';
|
1834
|
}
|
1835
|
if(count($whereList) !=0)
|
1836
|
$query .= " and ".implode(" and ",$whereList);
|
1837
|
if($groupby!='' && $selectedData['color']!= 'yes')
|
1838
|
$query .= " group by ".$groupby;
|
1839
|
if($orderby!='')
|
1840
|
$query .= " order by ".$orderby;
|
1841
|
//echo "NOT GROUP"; echo $query;
|
1842
|
$this->log->info("generated query: ".$query);
|
1843
|
$res = $this->doQuery($query, PDO::FETCH_NUM);
|
1844
|
//print_r($res);
|
1845
|
//$this->log->info('result set:'.json_encode($res));
|
1846
|
if($isMeas) $returnType = 'scatter';
|
1847
|
else $returnType = 'chart';
|
1848
|
return array('type'=>$returnType,'data'=>$res,'accomDims'=>$dimsList['fields']);
|
1849
|
}
|
1850
|
|
1851
|
function queryAllDims($tablename) {
|
1852
|
//get all the dims of the fact table and make a list with all their keys
|
1853
|
$fields = array();
|
1854
|
$joins = array();
|
1855
|
//find the factable
|
1856
|
$table = $this->findTable($tablename,'fact');
|
1857
|
if($table == false) {
|
1858
|
return false;
|
1859
|
}
|
1860
|
foreach($table['dim'] as $dim) {
|
1861
|
if(isset($dim['dimtable']) && $dim['dimtable'] == 'no') {//will need no join
|
1862
|
$fields[] = $dim['name'];
|
1863
|
}
|
1864
|
else{
|
1865
|
//find the key(s) put them in the fields list
|
1866
|
$key = $this->getDimsKeys($dim['name']);
|
1867
|
if(is_array($key)){
|
1868
|
foreach($key as $k)
|
1869
|
$k = "'".$k."'";
|
1870
|
$fields[] = implode(" || ",$key);
|
1871
|
}
|
1872
|
else
|
1873
|
$fields[] = $key;
|
1874
|
//and put it in the join list
|
1875
|
$joins[] = $dim['name'];
|
1876
|
}
|
1877
|
}
|
1878
|
return array('fields'=>$fields,'joins'=>$joins);
|
1879
|
}
|
1880
|
}
|
1881
|
|
1882
|
class QueryTree {
|
1883
|
public $tree = Array();
|
1884
|
|
1885
|
public function __construct($table) {
|
1886
|
$this->tree['table'] = $table;
|
1887
|
$this->tree['chains'] = Array();
|
1888
|
$this->tree['order'] = 'ASC';
|
1889
|
}
|
1890
|
|
1891
|
public function updateFilters($filters) {
|
1892
|
for ($i = 0; $i < count($filters); $i++) {
|
1893
|
$filterFields = explode("-", $filters[$i]['name']);
|
1894
|
$rootField = $filterFields[0];
|
1895
|
|
1896
|
$field = $filterFields[count($filterFields) - 1];
|
1897
|
$filter = Array();
|
1898
|
|
1899
|
$filter["column"] = $field;
|
1900
|
if (isset($filters[$i]['values']))
|
1901
|
$filter['values'] = $filters[$i]['values'];
|
1902
|
if (isset($filters[$i]['max']))
|
1903
|
$filter['max'] = $filters[$i]['max'];
|
1904
|
if (isset($filters[$i]['min']))
|
1905
|
$filter['min'] = $filters[$i]['min'];
|
1906
|
if (isset($filters[$i]['exvalues']))
|
1907
|
$filter['exvalues'] = $filters[$i]['exvalues'];
|
1908
|
|
1909
|
if (count($filterFields) > 1) {
|
1910
|
$this->buildChain($filters[$i]['name']);
|
1911
|
$this->tree['chains'][$rootField]['tables'][count($filterFields) - 2]['filters'][] = $filter;
|
1912
|
} else {
|
1913
|
$this->tree['filters'][] = $filter;
|
1914
|
}
|
1915
|
}
|
1916
|
}
|
1917
|
|
1918
|
public function updateYAxis($yAxisFields) {
|
1919
|
foreach ($yAxisFields as $field)
|
1920
|
$this->tree['yAxis'][] = $field['agg'] . '("' . $this->tree['table'] . '"."' . $field['fld'] . '")';
|
1921
|
}
|
1922
|
|
1923
|
public function updateXAxis($xAxisField) {
|
1924
|
$fields = explode("-", $xAxisField);
|
1925
|
|
1926
|
if (count($fields) == 1) {
|
1927
|
$this->tree['xAxis'] = '"'. $this->tree['table'] .'"."' . $fields[0] . '"';
|
1928
|
} else {
|
1929
|
if (!isset($this->tree['chains'][$fields[0]])) {
|
1930
|
$this->buildChain($xAxisField);
|
1931
|
}
|
1932
|
|
1933
|
$this->tree['xAxis'] = '"' . $fields[0] . '"."' . $fields[count($fields) - 1] . '"';
|
1934
|
$this->tree['chains'][$fields[0]]['return'] = '"'.$fields[count($fields) - 2] . '"."' . $fields[count($fields) - 1] . '"';
|
1935
|
}
|
1936
|
}
|
1937
|
|
1938
|
public function excludeNulls($exclude = true) {
|
1939
|
$this->tree['excludeNulls'] = $exclude;
|
1940
|
}
|
1941
|
|
1942
|
public function updateOrderBy($orderBy) {
|
1943
|
if ($orderBy == 'xaxis') {
|
1944
|
$this->tree['orderBy'] = $this->tree['xAxis'];
|
1945
|
} else {
|
1946
|
$fields = explode('-', $orderBy);
|
1947
|
|
1948
|
$this->tree['orderBy'] = $fields[0] . '("' . $this->tree['table'] . '"."' . $fields[1] . '")';
|
1949
|
}
|
1950
|
}
|
1951
|
|
1952
|
public function updateOrder($order) {
|
1953
|
if ($order == 'd') {
|
1954
|
$this->tree['order'] = 'DESC';
|
1955
|
}
|
1956
|
}
|
1957
|
|
1958
|
public function updateLimit($limit) {
|
1959
|
$this->tree['limit'] = $limit;
|
1960
|
}
|
1961
|
|
1962
|
public function getQuery() {
|
1963
|
$query = 'SELECT ' . $this->tree['xAxis'] . ' as xfield';
|
1964
|
|
1965
|
if (isset($this->tree['yAxis'])) {
|
1966
|
for ($i = 0; $i < count($this->tree['yAxis']); $i++) {
|
1967
|
|
1968
|
$query .= ', ';
|
1969
|
|
1970
|
if ($i < count($this->tree['yAxis']) - 1) {
|
1971
|
$query .= ' , ';
|
1972
|
}
|
1973
|
|
1974
|
$query .= $this->tree['yAxis'][$i] . ' as field' . $i;
|
1975
|
}
|
1976
|
}
|
1977
|
|
1978
|
$query .= ' FROM ' . $this->tree['table'];
|
1979
|
|
1980
|
foreach ($this->tree['chains'] as $chainName => $chain) {
|
1981
|
$query .= ' JOIN (' . $this->buildSubQuery($chain) . ') as ' .$chainName . ' ON "' . $this->tree['table'] . '"."' . $chainName . '" = "' . $chainName . '"."id"' ;
|
1982
|
}
|
1983
|
|
1984
|
if (isset($this->tree['excludeNulls']) || isset($this->tree['filters'])) {
|
1985
|
$query .= ' WHERE ';
|
1986
|
}
|
1987
|
|
1988
|
if (isset($this->tree['excludeNulls'])) {
|
1989
|
$query .= $this->tree['xAxis'] . ' IS NOT NULL';
|
1990
|
}
|
1991
|
|
1992
|
if (isset($this->tree['filters'])) {
|
1993
|
if (substr_compare($query, ' WHERE ', -strlen(' WHERE '), strlen(' WHERE ')) !== 0)
|
1994
|
$query .= ' AND ';
|
1995
|
|
1996
|
for ($i = 0; $i < count($this->tree['filters']); $i++) {
|
1997
|
$query .= '(' . $this->buildSubQueryFilter($this->tree['table'], $this->tree['filters'][$i]) .')';
|
1998
|
|
1999
|
if ($i < count($this->tree['filters']) - 1)
|
2000
|
$query .= ' AND ';
|
2001
|
}
|
2002
|
}
|
2003
|
|
2004
|
$query .= ' GROUP BY ' . $this->tree['xAxis'];
|
2005
|
|
2006
|
if (isset($this->tree['orderBy'])) {
|
2007
|
$query .= ' ORDER BY ' . $this->tree['orderBy'] . ' ' . $this->tree['order'];
|
2008
|
}
|
2009
|
|
2010
|
if (isset($this->tree['limit'])) {
|
2011
|
$query .= ' LIMIT ' . $this->tree['limit'];
|
2012
|
}
|
2013
|
|
2014
|
return $query;
|
2015
|
}
|
2016
|
|
2017
|
public function getTree() {
|
2018
|
return $this->tree;
|
2019
|
}
|
2020
|
|
2021
|
/* Helper functions */
|
2022
|
|
2023
|
private function buildChain($fieldsString) {
|
2024
|
$fields = explode("-", $fieldsString);
|
2025
|
$rootField = $fields[0];
|
2026
|
|
2027
|
if (!isset($this->tree['chains'][$rootField])) {
|
2028
|
$this->tree['chains'][$rootField] = Array();
|
2029
|
$this->tree['chains'][$rootField]['name'] = $rootField;
|
2030
|
}
|
2031
|
|
2032
|
for ($fc = 0; $fc < count($fields) - 1; $fc++) {
|
2033
|
$field = $fields[$fc];
|
2034
|
|
2035
|
if (!isset($this->tree['chains'][$rootField]['tables'][$fc]) ) {
|
2036
|
$this->tree['chains'][$rootField]['tables'][] = Array("table" => $field);
|
2037
|
}
|
2038
|
|
2039
|
}
|
2040
|
}
|
2041
|
|
2042
|
private function buildSubQuery($chain) {
|
2043
|
$subQuery = 'select distinct "' . $chain['tables'][0]['table'] . '"."id"';
|
2044
|
|
2045
|
if (isset($chain['return']))
|
2046
|
$subQuery .= ', ' . $chain['return'];
|
2047
|
|
2048
|
$subQuery .= ' from "' . $chain['tables'][0]['table'] . '"';
|
2049
|
|
2050
|
for ($i = 1; $i < count($chain['tables']); $i++) {
|
2051
|
$subQuery .= ' join "' . $chain['tables'][$i]['table'] .'" on "' . $chain['tables'][$i]['table'] . '"."id"="'.$chain['tables'][$i-1]['table'].'"."'.$chain['tables'][$i]['table'].'"';
|
2052
|
|
2053
|
if (isset($chain['tables'][$i]['filters'])) {
|
2054
|
foreach ($chain['tables'][$i]['filters'] as $filter) {
|
2055
|
$subQuery .= ' and (' . $this->buildSubQueryFilter($chain['tables'][$i]['table'], $filter) . ') ';
|
2056
|
}
|
2057
|
}
|
2058
|
}
|
2059
|
|
2060
|
return $subQuery;
|
2061
|
}
|
2062
|
|
2063
|
private function buildSubQueryFilter($tableName, $filter) {
|
2064
|
$column = $filter['column'];
|
2065
|
$filterText = "";
|
2066
|
|
2067
|
if (isset($filter['values'])) {
|
2068
|
for ($fc = 0; $fc < count($filter['values']); $fc++) {
|
2069
|
$value = $filter['values'][$fc];
|
2070
|
|
2071
|
if ($fc > 0)
|
2072
|
$filterText .= ' or ';
|
2073
|
$filterText .= '"' . $tableName . '"."'.$column.'" = \'' . $value . '\'';
|
2074
|
}
|
2075
|
} else if ( isset($filter['exvalues'])) {
|
2076
|
for ($fc = 0; $fc < count($filter['exvalues']); $fc++) {
|
2077
|
$value = $filter['exvalues'][$fc];
|
2078
|
|
2079
|
if ($fc > 0)
|
2080
|
$filterText .= ' and ';
|
2081
|
$filterText .= '"' . $tableName . '"."'.$column.'" != \'' . $value . '\'';
|
2082
|
}
|
2083
|
} else if (isset($filter['max'])) {
|
2084
|
if (strstr($column, 'year') && $filter['max'] == 'today') {
|
2085
|
$filterText = $column . ' <= extract(YEAR from now()) and ' . $column . ' >= ' . $filter['min'];
|
2086
|
} else if (strstr($column, 'year') && $filter['min'] == 'today') {
|
2087
|
$filterText = $column . ' >= extract(YEAR from now()) and ' . $column . ' <= ' . $filter['max'];
|
2088
|
} else {
|
2089
|
$filterText = $column . ' >= ' . $filter['min'] . ' and ' . $column . ' <= ' . $filter['max'];
|
2090
|
}
|
2091
|
}
|
2092
|
|
2093
|
return $filterText;
|
2094
|
}
|
2095
|
}
|
2096
|
|
2097
|
?>
|