处理可以挽救的异常

返回值 true 表示重新执行 query

@param array $aError 执行 query 后的报错信息
@param string $sQuery
@param array $aParam
@access protected
@throws DBException
@return bool
498973
protected function _parseException(string $sErrorCode) {

		// 42S02 table doesn't exist
		if ($sErrorCode === '42S02') {
			if (!$this->_aAutoCreateTable) {
				return FALSE;
			}
			$this->_connect();
			$this->cloneTableStructure(
				$this->_aAutoCreateTable['source'],
				$this->_aAutoCreateTable['target']
			);
			$this->_aAutoCreateTable = NULL;
			return TRUE;
		}

		// HY000 lost connect (MySQL server has gone away)
		if ($sErrorCode === 'HY000') {
			$this->_oPDO = NULL;
			$this->_connect();
			return TRUE;
		}

		return FALSE;
	}
603283
function _query($sql,$iarr=false)
	{

		if (!$this->autoCommit && $this->_transactionID) {
			$conn = $this->_transactionID;
			$docommit = false;
		} else {
			$conn = $this->_connectionID;
			$docommit = true;
		}
		if (is_array($sql)) {
			$fn = 'ibase_execute';
			$sql = $sql[1];
			if (is_array($iarr)) {
				if  (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
					if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
					$fnarr = array_merge( array($sql) , $iarr);
					$ret = call_user_func_array($fn,$fnarr);
				} else {
					switch(sizeof($iarr)) {
					case 1: $ret = $fn($sql,$iarr[0]); break;
					case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
					case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
					case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
					case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
					case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
					case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
					default: ADOConnection::outp( "Too many parameters to ibase query $sql");
					case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
					}
				}
			} else $ret = $fn($sql);
		} else {
			$fn = 'ibase_query';

			if (is_array($iarr)) {
				if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
					if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
					$fnarr = array_merge( array($conn,$sql) , $iarr);
					$ret = call_user_func_array($fn,$fnarr);
				} else {
					switch(sizeof($iarr)) {
					case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
					case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
					case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
					case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
					case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
					case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
					case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
					default: ADOConnection::outp( "Too many parameters to ibase query $sql");
					case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
					}
				}
			} else $ret = $fn($conn,$sql);
		}
		if ($docommit && $ret === true) {
			ibase_commit($this->_connectionID);
		}

		$this->_handleerror();
		return $ret;
	}
1203366
final public function insert(array $arr = [])
    {
        if (!$this->pdo) {
            throw  new Exception('您还没有连接数据库', Exception::CODE_UNCONNECT_DATABASE);
        }
        $keys = [];
        if (count($arr) === 0) {
            return false;
        }
        $temp = $arr;
        $ele = array_pop($temp);
        if (is_array($ele)) {
            $keys = array_keys($ele);
        } else {
            $keys = array_keys($arr);
            $arr = [$arr];
        }
        //整理keys
        $params = array_map(function ($item) {
            return ':' . $item;
        }, $keys);
        $keys = array_map(function ($item) {
            return $this->formatColumn($item);
        }, $keys);

        $sql = "insert into " . $this->getTable() . " (" . implode(',', $keys) . ") values (" . implode(',', $params) . ")";
        $this->sql = $sql;
        /**
         * 只获取sql
         */
        if ($this->justSql) {
            return true;
        }
        $sth = $this->pdo->prepare($sql);
        $lastid = null;
        !$this->_begintransaction && count($arr) > 1 && $this->pdo->beginTransaction();
        foreach ($arr as $val) {
            $sth->execute($val);
            $lastid = $this->pdo->lastInsertId();
        }
        !$this->_begintransaction && count($arr) > 1 && $this->pdo->commit();
        $this->lastQueryAt = time();
        $this->resetCon();
        return $lastid;
    }
822019
private static function executeQuery($db, $method, array $args)
    {
        self::$query_count++;
        self::debugStart(current($args)); // sql is always the first arg
        $ret = call_user_func_array(array($db, $method), $args);
        self::debugEnd();

        if (MDB2::isError($ret)) {
            throw new SwatDBException($ret);
        }

        return $ret;
    }
143252
function _query($sql,$inputarr=false)
	{
		$this->_errorMsg = false;
		if (is_array($inputarr)) {

			# bind input params with sp_executesql:
			# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
			# works only with sql server 7 and newer
            $getIdentity = false;
            if (!is_array($sql) && preg_match('/^\\s*insert/i', $sql)) {
                $getIdentity = true;
                $sql .= (preg_match('/;\\s*$/i', $sql) ? ' ' : '; ') . $this->identitySQL;
            }
			if (!is_array($sql)) $sql = $this->Prepare($sql);
			$params = '';
			$decl = '';
			$i = 0;
			foreach($inputarr as $v) {
				if ($decl) {
					$decl .= ', ';
					$params .= ', ';
				}
				if (is_string($v)) {
					$len = strlen($v);
					if ($len == 0) $len = 1;

					if ($len > 4000 ) {
						// NVARCHAR is max 4000 chars. Let's use NTEXT
						$decl .= "@P$i NTEXT";
					} else {
						$decl .= "@P$i NVARCHAR($len)";
					}

					$params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
				} else if (is_integer($v)) {
					$decl .= "@P$i INT";
					$params .= "@P$i=".$v;
				} else if (is_float($v)) {
					$decl .= "@P$i FLOAT";
					$params .= "@P$i=".$v;
				} else if (is_bool($v)) {
					$decl .= "@P$i INT"; # Used INT just in case BIT in not supported on the user's MSSQL version. It will cast appropriately.
					$params .= "@P$i=".(($v)?'1':'0'); # True == 1 in MSSQL BIT fields and acceptable for storing logical true in an int field
				} else {
					$decl .= "@P$i CHAR"; # Used char because a type is required even when the value is to be NULL.
					$params .= "@P$i=NULL";
					}
				$i += 1;
			}
			$decl = $this->qstr($decl);
			if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
			$rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params", $this->_connectionID);
            if ($getIdentity) {
                $arr = @mssql_fetch_row($rez);
                $this->lastInsID = isset($arr[0]) ? $arr[0] : false;
                @mssql_data_seek($rez, 0);
            }

		} else if (is_array($sql)) {
			# PrepareSP()
			$rez = mssql_execute($sql[1]);
            $this->lastInsID = false;

		} else {
			$rez = mssql_query($sql,$this->_connectionID);
            $this->lastInsID = false;
		}
		return $rez;
	}
712336
public function runMutativeQuery($updateQuery)
    {
        //clear num affected records
        $this->_numAffectedRecords = null;

        try {
            $DbResultStatementObj = $this->getDataSrcAdaptor()->query($updateQuery);

            if (!(is_object($DbResultStatementObj))) {
                $SQLmessage = 'no statement returned for update query: '
                    . $updateQuery;
                throw new Xandria_Db_SQLException($SQLmessage);
            }

            $this->_numAffectedRecords = $DbResultStatementObj->rowCount();

            return TRUE;
        } catch (Exception $e) {
            $SQLmessage = 'SQL Update Error Whilst runing update/mutative query '
                . $e->getMessage()
                . ' '
                . $updateQuery;

            throw new Xandria_Db_SQLException($SQLmessage);
        }
    }
983366
public function call(): void
    {
        $sql = $this->makeSql(self::TYPE_FUNCTION_QUERY, $this->sql, self::UNLIMIT);
        $result = pg_query($this->handle, $sql);

        $errorText = pg_last_error($this->handle);
        if ($errorText) {
            throw new DbRaiseException($errorText . ' : ' . $this->sql);
        }

        if ($result === false) {
            $msg = vsprintf('Error to exec sql "%s"', [$this->sql,]);
            throw new DbBadSqlException($msg, DbBadSqlException::ERROR_TO_EXEC_SQL);
        }
    }
960503
final function Query($qry)
    {
        $GLOBALS['qry_count']++;
        $GLOBALS['qry'].=$GLOBALS['qry_count'].':'.$qry."\n";

        $this->last_query = $qry;

        $this->query_result = $this->ExecQuery($qry);

        if ($this->query_result) {
            $this->SetQuerySummary();
            return $this->query_result;
        }

        $this->SetErrCode();
        if (!$this->show_errors) {
            $this->WriteError($this->GetErr());
        }

        return false;
    }
1316134
function _connect($argHostname, $argUsername, $argPassword, $argProvider= 'MSDASQL')
	{
		$u = 'UID';
		$p = 'PWD';

		if (!empty($this->charPage))
			$dbc = new COM('ADODB.Connection',null,$this->charPage);
		else
			$dbc = new COM('ADODB.Connection');

		if (! $dbc) return false;

		/* special support if provider is mssql or access */
		if ($argProvider=='mssql') {
			$u = 'User Id';  //User parameter name for OLEDB
			$p = 'Password';
			$argProvider = "SQLOLEDB"; // SQL Server Provider

			// not yet
			//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";

			//use trusted conection for SQL if username not specified
			if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
		} else if ($argProvider=='access')
			$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider

		if ($argProvider) $dbc->Provider = $argProvider;

		if ($argUsername) $argHostname .= ";$u=$argUsername";
		if ($argPassword)$argHostname .= ";$p=$argPassword";

		if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
		// @ added below for php 4.0.1 and earlier
		@$dbc->Open((string) $argHostname);

		$this->_connectionID = $dbc;

		$dbc->CursorLocation = $this->_cursor_location;
		return  $dbc->State > 0;
	}
189565
public static function collection($sType, array $aMessage) {

		self::$_iStep++;
		if (self::$_iStep > 1000) {
			return FALSE;
		}

		if (!self::init()) {
			return FALSE;
		}

		$iType = array_search((string)$sType, self::$_lType);
		if (!$iType) {
			throw new TangoException('unknown type "'.$sType.'"');
		}

		$oDB = DB::getInstance('_debug');
		if (!self::$_iAI) {
			self::$_iAI = $oDB->genAI('id_gen');
		}

		if (self::$_iStep == 1) {
			$aMessage['_init'] = [
				'sapi' => PHP_SAPI,
				'server_ip' => $_SERVER['SERVER_ADDR'],
				'client_ip' => $_SERVER['REMOTE_ADDR'],
				'uri' => $_SERVER['REQUEST_URI'],
				'time' => $_SERVER['REQUEST_TIME'],
				'elapsed' => microtime(TRUE) - $_SERVER['REQUEST_TIME_FLOAT'],
			];
		}

		$sQuery = 'INSERT INTO log '
			.'SET id = '.self::$_iAI.', '
			.'step = '.self::$_iStep.', '
			.'type = '.$iType.', '
			.'data = 0x'.bin2hex(gzcompress(json_encode($aMessage, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)));
		return $oDB->exec($sQuery);
	}
1266440
public function execute(array $inputParameters = null): bool
    {
        if(null !== $inputParameters)
        {
            foreach($inputParameters as $k => $v)
            {
                if(is_numeric($k))
                {
                    $this->statement->bindValue($k + 1, $v, $this->getDataTypeByValue($v));
                }
                else
                {
                    $this->statement->bindValue($k, $v, $this->getDataTypeByValue($v));
                }
            }
        }
        $result = $this->statement->execute();
        if(!$result)
        {
            throw new DbException('sql query error: [' . $this->errorCode() . '] ' . $this->errorInfo() . ' sql: ' . $this->getSql());
        }
        return $result;
    }
1104421
public function fetchAssocBySql ($strSQL, $arrBindParams = array ())
	{

		// Prepare query

		$query = $this->prepare ($strSQL);

		// Bind values
		
		if (!$this->bindValues ($query, $arrBindParams))
		{
			return FALSE;
		}

		// query execution status

		$success = $query->execute ();

		if (!$success)
		{
			return FALSE;
		}

		return $query->fetchAll (2);

	}
860259
protected function __execute(array $inputParameters = null)
    {
        $params = $this->getExecuteParams($inputParameters);
        $result = $this->statement->execute($params);
        yield $result;
        $result = yield;
        $this->binds = [];
        if(false === $result)
        {
            throw new DbException('sql query error: [' . $this->errorCode() . '] ' . $this->errorInfo() . ' sql: ' . $this->getSql());
        }
        else
        {
            $this->data = $result;
            $this->cursor = 0;
            return true;
        }
    }
1167672
public function query($pQuery, array $pParams = array())
    {
        $this->_stm = Agl::app()->getDb()->getConnection()->prepare($pQuery);

        if (! $this->_stm->execute($pParams)) {
            $error = $this->_stm->errorInfo();
            throw new Exception("The query failed with message '" . $error[2] . "'");
        }

        if (Agl::app()->isDebugMode()) {
            Agl::app()->getDb()->incrementCounter();
        }

        return $this->_stm->fetchAll(PDO::FETCH_ASSOC);
    }
1224439
public function query($sQuery)
    {
        $sQuery = $this->replaceConstants($sQuery);
        $this->iQueryCount++;
        $this->sLastQuery = $sQuery;

        return $this->oDb->query($sQuery);
    }
1198375
public function check($exceptionOnError = false)
    {
        $attributes = array_keys($this->validations);

        $this->setErrorMessages([]);

        foreach ($attributes as $attribute) {

            $attributeExists = array_key_exists($attribute, $this->data);
            $attributeNull = true;

            if($attributeExists){
                $attributeNull = is_bool($this->data[$attribute]) || is_int($this->data[$attribute]) ? false : is_null($this->data[$attribute]) || empty($this->data[$attribute]);
            }

            $isNullable = in_array($attribute, $this->getNullable());
            $attirbuteRoles = $this->getValidations($attribute);

            if (!$attributeNull && !empty($attirbuteRoles)) {
                foreach ($attirbuteRoles as $role) {
                    try {
                        $role['validation']::getInstance()->setAttribute($attribute);

                        $this->data[$attribute] = $role['validation']::getInstance()
                            ->validate($this->data[$attribute], $role['arguments']);

                    } catch (Exception $e) {
                        $this->setErrorMessage($attribute, $e->getMessage());
                    }
                }
            } elseif ($attributeNull && $isNullable) {
                $this->data[$attribute] = null;
            } else {
                $this->setErrorMessage($attribute, "O atributo '{$attribute}' não pode ser nulo!");
            }
        }

        if ($this->isRemoveUnused()) {
            $sentAttributes = array_keys($this->data);

            foreach ($sentAttributes as $attribute) {
                if (!in_array($attribute, $attributes)) {
                    unset($this->data[$attribute]);
                }
            }
        }

        $this->setErro(!empty($this->errorMessages) ? true : false);

        if ($exceptionOnError && $this->isError()) {
            throw new MbException("Seus dados não passaram na validação!", 400, $this, $this->errorMessages);
        }

        return $this->isError();
    }
519498
public function deleteBy($whArr = [])
    {
        $this->mustBeDataModel();

        $where = \wf\db\QueryBuilder::whereArr($whArr ? $whArr : $this->pkvAsWhere());
        if(!trim($where)) {
            throw new \InvalidArgumentException('请传入删除记录的条件');
        }

        $exe = $this->getDb()->exec("DELETE FROM %t WHERE %x", [$this->table, $where]);

        if (false === $exe) {
            throw new Exception($this->getDb()->getLastErr());
        }

        return $exe;
    }