<?php
 abstract class vB_dB_Query { use vB_Trait_NoSerialize; const CONDITIONS_KEY = '#filters'; const FIELDS_KEY = '#fields'; const VALUES_KEY = '#values'; const TYPE_KEY = '#type'; const COLUMNS_KEY = '#columns'; const QUERYTYPE_KEY = '#querytype'; const OPERATOR_KEY = 'operator'; const PRIORITY_QUERY = '#priority'; const DEBUG_QUERY = '#debug'; const CONDITION_ALL = '#all'; const OPERATOR_LT = 'LT'; const OPERATOR_LTE = 'LTE'; const OPERATOR_GT = 'GT'; const OPERATOR_GTE = 'GTE'; const OPERATOR_EQ = 'EQ'; const OPERATOR_NE = 'NE'; const OPERATOR_BEGINS = 'BEGINS'; const OPERATOR_ENDS = 'ENDS'; const OPERATOR_INCLUDES = 'INCLUDES'; const OPERATOR_ISNULL = 'IS NULL'; const OPERATOR_ISNOTNULL = 'IS NOT NULL'; const OPERATOR_AND = '#AND'; const OPERATOR_NAND = '#NAND'; const OPERATOR_OR = '#OR'; const OPERATOR_FALSE = 'FALSE'; const VALUE_ISNULL = '#NULL'; const QUERY_SELECT = 's'; const QUERY_COUNT = 'co'; const QUERY_SUMMARY = 'sum'; const QUERY_STORED = 'st'; const QUERY_UPDATE ='u'; const QUERY_INSERT = 'i'; const QUERY_INSERTIGNORE = 'ig'; const QUERY_REPLACE = 'r'; const QUERY_MULTIPLEINSERT = 'mi'; const QUERY_DELETE = 'd'; const QUERY_METHOD = 'm'; const QUERY_DROP = 'dr'; const QUERY_CREATE = 'cr'; const QUERY_ALTER = 'a'; const PARAM_LIMIT = '#limit'; const PARAM_LIMITSTART = '#limit_start'; const PARAM_LIMITPAGE = '#limit_page'; const BITFIELDS_KEY = '#bitfields'; const BITFIELDS_SET = '#bitset'; const BITFIELDS_UNSET = '#bitunset'; const SORT_ASC = 'ASC'; const SORT_DESC = 'DESC'; const QUERY_TABLE = 't'; private static array $typemap = [ self::QUERY_STORED => 'Stored', self::QUERY_SELECT => 'Select', self::QUERY_COUNT => 'Summary', self::QUERY_SUMMARY => 'Summary', self::QUERY_UPDATE => 'Update', self::QUERY_INSERT => 'Insert', self::QUERY_INSERTIGNORE => 'InsertIgnore', self::QUERY_REPLACE => 'Replace', self::QUERY_DELETE => 'Delete', self::QUERY_MULTIPLEINSERT => 'MultipleInsert', self::QUERY_METHOD => 'Method', ]; protected static $queryBuilders = []; protected static vB_dB_Logger $logger; protected bool $logThis = false; protected $db = false; protected $dbSlave = false; protected $db_type; protected $data_loaded = false; protected $params = false; protected $queryid = false; protected $error = false; protected $query_data = []; protected $querydefs = false; public static function getQuery($queryid, $params, $db, $dbtype, $dbSlave) { if (!isset(self::$logger)) { self::$logger = vB_dB_Logger::getDefault(); } if (!isset(self::$queryBuilders[$dbtype])) { $queryClass = 'vB_Db_' . $dbtype . '_QueryBuilder'; self::$queryBuilders[$dbtype] = new $queryClass($db); } [$class, $queryid] = self::splitQueryId($dbtype, $queryid); $querydefs = new $class(self::$logger); $queryData = $querydefs->getQueryData(); $type = $params[self::TYPE_KEY] ?? null; if (!$type) { if (!empty($queryData[$queryid])) { $type = self::QUERY_STORED; } else if (method_exists($querydefs, $queryid)) { $type = self::QUERY_METHOD; } else { $type = self::QUERY_SELECT; } } if (!isset(self::$typemap[$type])) { throw new Exception('invalid_query_definition'); } $queryClass = 'vB_dB_' . $dbtype . '_Query_' . self::$typemap[$type]; $query = new $queryClass($queryid, $db, $dbSlave); $query->querydefs = $querydefs; $query->query_data = $queryData; $query->logThis = $params[self::DEBUG_QUERY] ?? false; return $query; } public static function splitQueryId(string $dbtype, string $queryid) : array { $values = explode(':', $queryid, 2); if (count($values) > 1) { [$class_prefix, $queryid] = $values; } else { $class_prefix = 'vB'; } $class = $class_prefix . '_dB_' . $dbtype . '_QueryDefs'; if (!class_exists($class)) { throw new Exception('Query class ' . $class . ' not found'); } return [$class, $queryid]; } protected function __construct($queryid, $db, $dbSlave) { $this->db = $db; $this->dbSlave = $dbSlave; $this->queryid = $queryid; } abstract public function setQuery(array $params, array|string $sortorder) : bool; abstract public function execSQL() : mixed; protected function logQuery(string $querystring) : void { self::$logger->log($querystring, $this->logThis); } } 