From 66ad8ba249a0094f727d512660012588dcddd7b0 Mon Sep 17 00:00:00 2001 From: runchance <93974235+runchance@users.noreply.github.com> Date: Sat, 20 Nov 2021 16:06:23 +0800 Subject: [PATCH] Lock supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The custom lock string is supported. 1、$where['LOCK'] = true (FOR UPDATE) 2、$where['LOCK'] = '{custom}' (custom) --- src/Medoo.php | 59 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/src/Medoo.php b/src/Medoo.php index bfc864b4..43f874e3 100644 --- a/src/Medoo.php +++ b/src/Medoo.php @@ -174,6 +174,14 @@ class Medoo */ public $errorInfo = null; + + /** + * The array of lockSql. + * + * @var array|null + */ + protected $lockSql = null; + /** * Connect the database. * @@ -553,7 +561,6 @@ public function exec(string $statement, array $map = [], callable $callback = nu foreach ($map as $key => $value) { $statement->bindValue($key, $value[0], $value[1]); } - if (is_callable($callback)) { $this->pdo->beginTransaction(); $callback($statement); @@ -1018,10 +1025,10 @@ protected function dataImplode(array $data, array &$map, string $conjunctor): st protected function whereClause($where, array &$map): string { $clause = ''; - + $this->lockSql = null; if (is_array($where)) { $conditions = array_diff_key($where, array_flip( - ['GROUP', 'ORDER', 'HAVING', 'LIMIT', 'LIKE', 'MATCH'] + ['GROUP', 'ORDER', 'HAVING', 'LIMIT', 'LIKE', 'MATCH', 'LOCK'] )); if (!empty($conditions)) { @@ -1142,6 +1149,32 @@ protected function whereClause($where, array &$map): string } } } + + if (isset($where['LOCK'])) { + $lock = ''; + if (is_bool($where['LOCK'])) { + $lock = $where['LOCK'] ? 'FOR UPDATE' : ''; + switch($this->type){ + case 'mssql': + $lock = ''; + $this->lockSql = $where['LOCK'] ? 'WITH(rowlock,updlock,holdlock)' : ''; + break; + case 'oracle': + $lock = $where['LOCK'] ? 'FOR UPDATE NOWAIT' : ''; + break; + } + }else{ + if (is_string($where['LOCK']) && !empty($where['LOCK'])) { + if($this->type==='mssql'){ + $this->lockSql = $where['LOCK'] ? 'WITH('.trim($lock).')' : ''; + }else{ + $lock = trim($lock); + } + } + } + $clause .= $lock ? ' ' . $lock : ''; + } + } elseif ($raw = $this->buildRaw($where, $map)) { $clause .= ' ' . $raw; } @@ -1178,7 +1211,7 @@ protected function selectContext( $table = $this->tableQuote($table); $tableQuery = $table; } - + $isJoin = $this->isJoin($join); if ($isJoin) { @@ -1221,8 +1254,22 @@ protected function selectContext( } else { $column = $this->columnPush($columns, $map, true, $isJoin); } - - return 'SELECT ' . $column . ' FROM ' . $tableQuery . $this->whereClause($where, $map); + $whereClause = $this->whereClause($where, $map); + if($this->lockSql){ + $explode = explode(' ',$tableQuery); + if(count($explode)==1){ + $tableQuery.= $this->lockSql ? ' '.$this->lockSql : ''; + }else{ + if($this->lockSql){ + if($explode[1]=='AS'){ + $tableQuery = str_replace($explode[0].' AS '.$explode[2],$explode[0].' AS '.$explode[2].' '.$this->lockSql,$tableQuery); + }else{ + $tableQuery = str_replace($explode[0].' ',$explode[0].' '.$this->lockSql,$tableQuery); + } + } + } + } + return 'SELECT ' . $column . ' FROM ' . $tableQuery . $whereClause; } /**