/** * 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; }
/** * 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; }