# TimeIntervalsGenerator.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2008 by Ivan Y. Khvostishkov                            *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    00009  *                                                                         *
    00010  ***************************************************************************/
    00011
    00015     final class TimeIntervalsGenerator extends QueryIdentification
    00016     {
    00017         const ITERATOR_ALIAS    = 'iterator';
    00018
    00019         private $range      = null;
    00020         private $interval   = null;
    00021
    00022         private $overlapped = true;
    00023
    00024         private $field      = 'time';
    00025
    00026         public static function create()
    00027         {
    00028             return new self;
    00029         }
    00030
    00031         public function setRange(DateRange $range)
    00032         {
    00033             $this->range = $range;
    00034
    00035             return $this;
    00036         }
    00037
    00041         public function getRange()
    00042         {
    00043             return $this->range;
    00044         }
    00045
    00046         public function setInterval(IntervalUnit $interval)
    00047         {
    00048             $this->interval = $interval;
    00049
    00050             return $this;
    00051         }
    00052
    00053         public function setOverlapped($overlapped = true)
    00054         {
    00055             Assert::isBoolean($overlapped);
    00056
    00057             $this->overlapped = ($overlapped === true);
    00058
    00059             return $this;
    00060         }
    00061
    00062         public function isOverlapped()
    00063         {
    00064             return $this->overlapped;
    00065         }
    00066
    00067         public function getField()
    00068         {
    00069             return $this->field;
    00070         }
    00071
    00072         public function setField($field)
    00073         {
    00074             $this->field = $field;
    00075
    00076             return $this;
    00077         }
    00078
    00082         public function getInterval()
    00083         {
    00084             return $this->interval;
    00085         }
    00086
    00087         public function toSelectQuery()
    00088         {
    00089             if (!$this->range || !$this->interval)
    00090                 throw new WrongStateException(
    00091                     'define time range and interval units first'
    00092                 );
    00093
    00094             if (!$this->range->getStart() || !$this->range->getEnd())
    00095                 throw new WrongArgumentException(
    00096                     'cannot operate with unlimited range'
    00097                 );
    00098
    00099             $firstIntervalStart =
    00100                 $this->interval->truncate(
    00101                     $this->range->getStart(), !$this->overlapped
    00102                 );
    00103
    00104             $maxIntervals =
    00105                 $this->interval->countInRange(
    00106                     $this->range, $this->overlapped
    00107                 ) - 1;
    00108
    00109             $generator = $this->getSeriesGenerator(0, $maxIntervals);
    00110
    00111             $result = OSQL::select()->
    00112                 from($generator, self::ITERATOR_ALIAS)->
    00113                 get(
    00114                     Expression::add(
    00115                         DBValue::create($firstIntervalStart->toString())->
    00116                         castTo(
    00117                             DataType::create(DataType::TIMESTAMP)->
    00118                             getName()
    00119                         ),
    00120
    00121                         Expression::mul(
    00122                             DBValue::create("1 {$this->interval->getName()}")->
    00123                             castTo(
    00124                                 DataType::create(DataType::INTERVAL)->
    00125                                 getName()
    00126                             ),
    00127
    00128                             DBField::create(self::ITERATOR_ALIAS)
    00129                         )
    00130                     ),
    00131                     $this->field
    00132                 );
    00133
    00134             return $result;
    00135         }
    00136
    00137         public function toDialectString(Dialect $dialect)
    00138         {
    00139             return $this->toSelectQuery()->toDialectString($dialect);
    00140         }
    00141
    00149         private function getSeriesGenerator($start, $stop, $step = null)
    00150         {
    00151             if (!$step)
    00152                 $result = SQLFunction::create(
    00153                     'generate_series',
    00154                     DBValue::create($start)->
    00155                     castTo(DataType::create(DataType::INTEGER)->getName()),
    00156
    00157                     DBValue::create($stop)->
    00158                     castTo(DataType::create(DataType::INTEGER)->getName())
    00159                 );
    00160             else
    00161                 $result = SQLFunction::create(
    00162                     'generate_series',
    00163                     DBValue::create($start)->
    00164                     castTo(DataType::create(DataType::INTEGER)->getName()),
    00165
    00166                     DBValue::create($stop)->
    00167                     castTo(DataType::create(DataType::INTEGER)->getName()),
    00168
    00169                     DBValue::create($step)->
    00170                     castTo(DataType::create(DataType::INTEGER)->getName())
    00171                 );
    00172
    00173             return $result;
    00174         }
    00175     }
    00176 ?>