Ejemplo n.º 1
0
 function GetSQL(CACHEDB &$cache, $table = false, $limit = 0, $use_subseconds = false, $sequence = false, $sampling = 0)
 {
     global $MYSQL_FORCE_INDEXES;
     $res = array();
     if (!$limit) {
         $limit = $this->GetItemLimit();
     }
     if ($limit) {
         $res['limit'] = " LIMIT " . abs($limit);
     } else {
         $res['limit'] = "";
     }
     if ($sequence === false) {
         $sequence = $this->sequence;
     }
     $from = $this->GetWindowStart();
     $ifrom = floor($from);
     if ($sequence == INTERVAL::SEQUENCE_UNSORTED) {
         $res['sort'] = "";
     } elseif ($limit < 0 || $sequence == INTERVAL::SEQUENCE_BACKWARD) {
         $res['sort'] = "ORDER BY `id` DESC";
     } else {
         $res['sort'] = "ORDER BY `id` ASC";
     }
     if ($use_subseconds) {
         $res['list'] = "EXTENDED_UNIX_TIMESTAMP(time) AS timestamp, `ns`";
     } else {
         $res['list'] = "EXTENDED_UNIX_TIMESTAMP(time) AS timestamp";
     }
     if ($this->IsEmpty()) {
         $res['cond'] = "WHERE (`id` = NULL)";
         return $res;
     }
     if ($this->window_size > 0) {
         $to = $this->GetWindowEnd();
         $ito = floor($to);
         if ($use_subseconds) {
             if ($from == $ifrom) {
                 $nfrom = 0;
             } else {
                 $nfrom = round(1000000000 * ("0" . strstr($from, ".")));
             }
             if ($to == $ito) {
                 $nto = 0;
             } else {
                 $nto = round(1000000000 * ("0" . strstr($to, ".")));
             }
         } else {
             $nfrom = 0;
             $nto = 0;
         }
         $res['cond'] = "WHERE ((`id` >= ADEI_TIMESTAMP({$ifrom}, {$nfrom})) AND (`id` < ADEI_TIMESTAMP({$ito}, {$nto})))";
     } else {
         if ($this->sequence == INTERVAL::SEQUENCE_BACKWARD) {
             $sign = '<';
         } else {
             $sign = '>';
         }
         $sqlfrom = $cache->SQLTime($ifrom);
         if ($use_subseconds && $ifrom != $from) {
             $nfrom = round(1000000000 * ("0" . strstr($from, ".")));
         } else {
             $nfrom = 0;
         }
         $res['cond'] = "WHERE `id` {$sign} ADEI_TIMESTAMP({$ifrom}, {$nfrom})";
     }
     if ($sampling) {
         if (!$table) {
             throw new ADEIException(translate("Ineternal Error: The table name should be passed to query generator if resampling is needed"));
         }
         $sampling *= 1000000000;
         /*
         	The first command is terribly slow, and the second should be avoided
         	because we want floating timestamp start.
         
                 $groupping = "FLOOR((`id` - ADEI_TIMESTAMP($ifrom, $nfrom)) / $sampling)";
                 $groupping = "FLOOR((`id` - 1000000000*$from) / $sampling)";
         */
         $groupping = "FLOOR(`id` / {$sampling})";
         if ($MYSQL_FORCE_INDEXES) {
             $idx_fix = "FORCE INDEX (id)";
         } else {
             $idx_fix = "";
         }
         $res['join'] = ", (SELECT MAX(`id`) AS tmptbl_id FROM `{$table}` {$idx_fix} {$res['cond']} GROUP BY {$groupping}) AS tmptbl";
         $res['cond'] = "WHERE tmptbl.tmptbl_id = `id`";
     }
     $res['index'] = "id";
     /*    
         if ($use_subseconds) {
             $res['list'] = "EXTENDED_UNIX_TIMESTAMP(time) AS timestamp, `ns`";
     	if (($sequence == INTERVAL::SEQUENCE_UNSORTED))
     	    $res['sort'] = "";
     	elseif (($limit < 0)||($sequence == INTERVAL::SEQUENCE_BACKWARD))
     	    $res['sort'] = "ORDER BY `time` DESC, `ns` DESC";
     	else
     	    $res['sort'] = "ORDER BY `time` ASC, `ns` ASC";
         } else {
             $res['list'] = "EXTENDED_UNIX_TIMESTAMP(time) AS timestamp";
     	if (($sequence == INTERVAL::SEQUENCE_UNSORTED))
     	    $res['sort'] = "";
     	elseif (($limit < 0)||($sequence == INTERVAL::SEQUENCE_BACKWARD))
     	    $res['sort'] = "ORDER BY `time` DESC";
     	else 
     	    $res['sort'] = "ORDER BY `time` ASC";
         }
         if ($this->window_size > 0) {
     	$to = dsMathPreciseAdd($this->window_start, $this->window_size);
     	$ito = floor($to);
     	if (($use_subseconds)&&(($ifrom != $from)||($ito != $to))) {
     	    if ($ifrom == $ito) {
     		$sqlfrom = $cache->SQLTime($ifrom);
     		if ($from == $ifrom) $nfrom = 0;
     		else $nfrom = round(1000000000*("0" . strstr($from, ".")));
     		if ($to == $ito) $nto = 0;
     		else $nto = round(1000000000*("0" . strstr($to, ".")));
     	        $res['cond'] = "WHERE ((`time` = $sqlfrom) AND (`ns` >= $nfrom) AND (`ns` < $nto))";
     	    } else {
     		$cond = "";
     	        if ($ifrom != $from) {
     		    $nfrom = round(1000000000*("0" . strstr($from, ".")));
     		    $sqlfrom = $cache->SQLTime($ifrom);
     		    $cond = "((`time` = $sqlfrom) AND (`ns` >= $nfrom))";
     		    $ifrom++;
     		}
     		if ($ifrom != $ito) {
     		    if ($cond) $cond .= " OR ";
     		    $sqlfrom = $cache->SQLTime($ifrom);
     	    	    $sqlto = $cache->SQLTime($ito);
         		    $cond .= "((`time` >= $sqlfrom) AND (`time` < $sqlto))";
     		} else $sqlto = false;
     		if ($ito != $to) {
     		    if ($cond) $cond .= " OR ";
     		    if (!$sqlto) $sqlto = $cache->SQLTime($ito);
     		
     		    $nto = round(1000000000*("0" . strstr($to, ".")));
     		    $cond .= "((`time` = $sqlto) AND (`ns` < $nto))";
     		}
     	
     		$res['cond'] = "WHERE ($cond)";
     	    }
     	} else {
     	    $sqlfrom = $cache->SQLTime($ifrom);
     	    $sqlto = $cache->SQLTime($ito);
         	    $res['cond'] = "WHERE ((`time` >= $sqlfrom) AND (`time` < $sqlto))";
     	}
         } else {
     	if ($this->sequence == INTERVAL::SEQUENCE_BACKWARD) $sign = '<';
     	else $sign = '>';
     	$sqlfrom = $cache->SQLTime($ifrom);
     	if (($use_subseconds)&&($ifrom != $from)) {
     	    $nfrom = round(1000000000*("0" . strstr($from, ".")));
     	    $res['cond'] = "WHERE (((`time` = $sqlfrom) AND (`ns` $sign $nfrom)) OR (`time` $sign $sqlfrom))";
     	} else {
     	    $res['cond'] = "WHERE `time` $sign $sqlfrom";
     	}
         }
         if ($sampling) {
     	if (!$table)
     	    throw new ADEIException(translate("Ineternal Error: The table name should be passed to query generator if resampling is needed"));
     	if ($use_subseconds) {
     	    $sampling*=1000000000;
     	    $rfrom = ($from - $ifrom)*1000000000;	    
     	    $groupping = "FLOOR(((EXTENDED_UNIX_TIMESTAMP(`time`) - $ifrom) * 1000000000 + (`ns` - $rfrom))/$sampling)";
     	    $res['join'] = ", (SELECT MIN(time) AS tmptbl_time, MIN($groupping) AS tmptbl_idx FROM $table {$res['cond']} GROUP BY $groupping) AS tmptbl";
     	    $res['cond'] = "WHERE tmptbl.tmptbl_time = `time` AND tmptbl.tmptbl_idx = $groupping";
     	} else {
     	    $groupping = "FLOOR((EXTENDED_UNIX_TIMESTAMP(`time`) - " . ($ifrom) . " )/$sampling)";
     	    $res['join'] = ", (SELECT MIN(`time`) AS tmptbl_time FROM $table {$res['cond']} GROUP BY $groupping) AS tmptbl";
     	    $res['cond'] = "WHERE tmptbl.tmptbl_time = `time`";
     	}
         }
     */
     #    echo print_r($res, true) . "\n";
     #    exit;
     return $res;
 }