Esempio n. 1
0
 /**
  * Generates SQL.
  *
  * @param  array
  * @return bool
  */
 public function translate(array $args)
 {
     $this->limit = -1;
     $this->offset = 0;
     $this->hasError = FALSE;
     $commandIns = NULL;
     $lastArr = NULL;
     // shortcuts
     $cursor =& $this->cursor;
     $cursor = 0;
     $this->args = array_values($args);
     $args =& $this->args;
     // conditional sql
     $this->ifLevel = $this->ifLevelStart = 0;
     $comment =& $this->comment;
     $comment = FALSE;
     // iterate
     $sql = array();
     while ($cursor < count($args)) {
         $arg = $args[$cursor];
         $cursor++;
         // simple string means SQL
         if (is_string($arg)) {
             // speed-up - is regexp required?
             $toSkip = strcspn($arg, '`[\'"%');
             if (strlen($arg) === $toSkip) {
                 // needn't be translated
                 $sql[] = $arg;
             } else {
                 $sql[] = substr($arg, 0, $toSkip) . preg_replace_callback('/(?=`|\\[|\'|"|%)(?:`(.+?)`|\\[(.+?)\\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|%([a-zA-Z]{1,4})(?![a-zA-Z]))/s', array($this, 'cb'), substr($arg, $toSkip));
             }
             continue;
         }
         if ($comment) {
             $sql[] = '...';
             continue;
         }
         if (is_array($arg)) {
             if (is_string(key($arg))) {
                 // associative array -> autoselect between SET or VALUES & LIST
                 if ($commandIns === NULL) {
                     $commandIns = strtoupper(substr(ltrim($args[0]), 0, 6));
                     $commandIns = $commandIns === 'INSERT' || $commandIns === 'REPLAC';
                     $sql[] = $this->formatValue($arg, $commandIns ? 'v' : 'a');
                 } else {
                     if ($lastArr === $cursor - 1) {
                         $sql[] = ',';
                     }
                     $sql[] = $this->formatValue($arg, $commandIns ? 'l' : 'a');
                 }
                 $lastArr = $cursor;
                 continue;
             } elseif ($cursor === 1) {
                 // implicit array expansion
                 $cursor = 0;
                 array_splice($args, 0, 1, $arg);
                 continue;
             }
         }
         // default processing
         $sql[] = $this->formatValue($arg, FALSE);
     }
     // while
     if ($comment) {
         $sql[] = "*/";
     }
     $sql = implode(' ', $sql);
     // apply limit
     if ($this->limit > -1 || $this->offset > 0) {
         $this->driver->applyLimit($sql, $this->limit, $this->offset);
     }
     $this->sql = $sql;
     return !$this->hasError;
 }
Esempio n. 2
0
 /**
  * Generates SQL.
  * @param  array
  * @return string
  * @throws DibiException
  */
 public function translate(array $args)
 {
     $this->identifiers = new DibiLazyStorage(array($this, 'delimite'));
     $args = array_values($args);
     while (count($args) === 1 && is_array($args[0])) {
         // implicit array expansion
         $args = array_values($args[0]);
     }
     $this->args = $args;
     $this->limit = -1;
     $this->offset = 0;
     $this->hasError = FALSE;
     $commandIns = NULL;
     $lastArr = NULL;
     // shortcuts
     $cursor =& $this->cursor;
     $cursor = 0;
     // conditional sql
     $this->ifLevel = $this->ifLevelStart = 0;
     $comment =& $this->comment;
     $comment = FALSE;
     // iterate
     $sql = array();
     while ($cursor < count($this->args)) {
         $arg = $this->args[$cursor];
         $cursor++;
         // simple string means SQL
         if (is_string($arg)) {
             // speed-up - is regexp required?
             $toSkip = strcspn($arg, '`[\'":%');
             if (strlen($arg) === $toSkip) {
                 // needn't be translated
                 $sql[] = $arg;
             } else {
                 $sql[] = substr($arg, 0, $toSkip) . preg_replace_callback('/(?=[`[\'":%?])(?:`(.+?)`|\\[(.+?)\\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z~][a-zA-Z0-9~]{0,5})|(\\?))/s', array($this, 'cb'), substr($arg, $toSkip));
                 if (preg_last_error()) {
                     throw new DibiPcreException();
                 }
             }
             continue;
         }
         if ($comment) {
             $sql[] = '...';
             continue;
         }
         if ($arg instanceof Traversable) {
             $arg = iterator_to_array($arg);
         }
         if (is_array($arg)) {
             if (is_string(key($arg))) {
                 // associative array -> autoselect between SET or VALUES & LIST
                 if ($commandIns === NULL) {
                     $commandIns = strtoupper(substr(ltrim($this->args[0]), 0, 6));
                     $commandIns = $commandIns === 'INSERT' || $commandIns === 'REPLAC';
                     $sql[] = $this->formatValue($arg, $commandIns ? 'v' : 'a');
                 } else {
                     if ($lastArr === $cursor - 1) {
                         $sql[] = ',';
                     }
                     $sql[] = $this->formatValue($arg, $commandIns ? 'l' : 'a');
                 }
                 $lastArr = $cursor;
                 continue;
             }
         }
         // default processing
         $sql[] = $this->formatValue($arg, FALSE);
     }
     // while
     if ($comment) {
         $sql[] = "*/";
     }
     $sql = implode(' ', $sql);
     if ($this->hasError) {
         throw new DibiException('SQL translate error', 0, $sql);
     }
     // apply limit
     if ($this->limit > -1 || $this->offset > 0) {
         $this->driver->applyLimit($sql, $this->limit, $this->offset);
     }
     return $sql;
 }