| Total Complexity | 43 |
| Total Lines | 352 |
| Duplicated Lines | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Complex classes like DoliDB often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DoliDB, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 30 | abstract class DoliDB implements Database |
||
| 31 | { |
||
| 32 | /** @var bool|resource|SQLite3 Database handler */ |
||
| 33 | public $db; |
||
| 34 | /** @var string Database type */ |
||
| 35 | public $type; |
||
| 36 | /** @var string Charset used to force charset when creating database */ |
||
| 37 | public $forcecharset = 'utf8'; |
||
| 38 | /** @var string Collate used to force collate when creating database */ |
||
| 39 | public $forcecollate = 'utf8_unicode_ci'; |
||
| 40 | /** @var resource Resultset of last query */ |
||
| 41 | private $_results; |
||
| 42 | /** @var bool true if connected, else false */ |
||
| 43 | public $connected; |
||
| 44 | /** @var bool true if database selected, else false */ |
||
| 45 | public $database_selected; |
||
| 46 | /** @var string Selected database name */ |
||
| 47 | public $database_name; |
||
| 48 | /** @var string Database username */ |
||
| 49 | public $database_user; |
||
| 50 | /** @var string Database host */ |
||
| 51 | public $database_host; |
||
| 52 | /** @var int Database port */ |
||
| 53 | public $database_port; |
||
| 54 | /** @var int >=1 if a transaction is opened, 0 otherwise */ |
||
| 55 | public $transaction_opened; |
||
| 56 | /** @var string Last successful query */ |
||
| 57 | public $lastquery; |
||
| 58 | /** @var string Last failed query */ |
||
| 59 | public $lastqueryerror; |
||
| 60 | /** @var string Last error message */ |
||
| 61 | public $lasterror; |
||
| 62 | /** @var string Last error number. For example: 'DB_ERROR_RECORD_ALREADY_EXISTS', '12345', ... */ |
||
| 63 | public $lasterrno; |
||
| 64 | |||
| 65 | /** @var string If we need to set a prefix specific to the database so it can be reused (when defined instead of MAIN_DB_PREFIX) to forge requests */ |
||
| 66 | public $prefix_db; |
||
| 67 | |||
| 68 | /** @var bool Status */ |
||
| 69 | public $ok; |
||
| 70 | /** @var string */ |
||
| 71 | public $error; |
||
| 72 | |||
| 73 | |||
| 74 | |||
| 75 | /** |
||
| 76 | * Return the DB prefix |
||
| 77 | * |
||
| 78 | * @return string The DB prefix |
||
| 79 | */ |
||
| 80 | public function prefix() |
||
| 81 | { |
||
| 82 | return (empty($this->prefix_db) ? MAIN_DB_PREFIX : $this->prefix_db); |
||
| 83 | } |
||
| 84 | |||
| 85 | /** |
||
| 86 | * Format a SQL IF |
||
| 87 | * |
||
| 88 | * @param string $test Test string (example: 'cd.statut=0', 'field IS NULL') |
||
| 89 | * @param string $resok resultat si test egal |
||
| 90 | * @param string $resko resultat si test non egal |
||
| 91 | * @return string SQL string |
||
| 92 | */ |
||
| 93 | public function ifsql($test, $resok, $resko) |
||
| 97 | } |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field. |
||
| 101 | * Function to use to build INSERT, UPDATE or WHERE predica |
||
| 102 | * |
||
| 103 | * @param int $param Date TMS to convert |
||
| 104 | * @param mixed $gm 'gmt'=Input informations are GMT values, 'tzserver'=Local to server TZ |
||
| 105 | * @return string Date in a string YYYY-MM-DD HH:MM:SS |
||
| 106 | */ |
||
| 107 | public function idate($param, $gm = 'tzserver') |
||
| 108 | { |
||
| 109 | // TODO $param should be gmt, so we should add $gm to 'gmt' instead of default 'tzserver' |
||
| 110 | return dol_print_date($param, "%Y-%m-%d %H:%M:%S", $gm); |
||
| 111 | } |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Return last error code |
||
| 115 | * |
||
| 116 | * @return string lasterrno |
||
| 117 | */ |
||
| 118 | public function lasterrno() |
||
| 119 | { |
||
| 120 | return $this->lasterrno; |
||
| 121 | } |
||
| 122 | |||
| 123 | /** |
||
| 124 | * Sanitize a string for SQL forging |
||
| 125 | * |
||
| 126 | * @param string $stringtosanitize String to escape |
||
| 127 | * @param int $allowsimplequote 1=Allow simple quotes in string. When string is used as a list of SQL string ('aa', 'bb', ...) |
||
| 128 | * @return string String escaped |
||
| 129 | */ |
||
| 130 | public function sanitize($stringtosanitize, $allowsimplequote = 0) |
||
| 131 | { |
||
| 132 | if ($allowsimplequote) { |
||
| 133 | return preg_replace('/[^a-z0-9_\-\.,\']/i', '', $stringtosanitize); |
||
| 134 | } else { |
||
| 135 | return preg_replace('/[^a-z0-9_\-\.,]/i', '', $stringtosanitize); |
||
| 136 | } |
||
| 137 | } |
||
| 138 | |||
| 139 | /** |
||
| 140 | * Start transaction |
||
| 141 | * |
||
| 142 | * @return int 1 if transaction successfuly opened or already opened, 0 if error |
||
| 143 | */ |
||
| 144 | public function begin() |
||
| 145 | { |
||
| 146 | if (!$this->transaction_opened) { |
||
| 147 | $ret = $this->query("BEGIN"); |
||
| 148 | if ($ret) { |
||
| 149 | $this->transaction_opened++; |
||
| 150 | dol_syslog("BEGIN Transaction", LOG_DEBUG); |
||
| 151 | dol_syslog('', 0, 1); |
||
| 152 | } |
||
| 153 | return $ret; |
||
| 154 | } else { |
||
| 155 | $this->transaction_opened++; |
||
| 156 | dol_syslog('', 0, 1); |
||
| 157 | return 1; |
||
| 158 | } |
||
| 159 | } |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Validate a database transaction |
||
| 163 | * |
||
| 164 | * @param string $log Add more log to default log line |
||
| 165 | * @return int 1 if validation is OK or transaction level no started, 0 if ERROR |
||
| 166 | */ |
||
| 167 | public function commit($log = '') |
||
| 168 | { |
||
| 169 | dol_syslog('', 0, -1); |
||
| 170 | if ($this->transaction_opened <= 1) { |
||
| 171 | $ret = $this->query("COMMIT"); |
||
| 172 | if ($ret) { |
||
| 173 | $this->transaction_opened = 0; |
||
| 174 | dol_syslog("COMMIT Transaction".($log ? ' '.$log : ''), LOG_DEBUG); |
||
| 175 | return 1; |
||
| 176 | } else { |
||
| 177 | return 0; |
||
| 178 | } |
||
| 179 | } else { |
||
| 180 | $this->transaction_opened--; |
||
| 181 | return 1; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | /** |
||
| 186 | * Cancel a transaction and go back to initial data values |
||
| 187 | * |
||
| 188 | * @param string $log Add more log to default log line |
||
| 189 | * @return resource|int 1 if cancelation is ok or transaction not open, 0 if error |
||
| 190 | */ |
||
| 191 | public function rollback($log = '') |
||
| 192 | { |
||
| 193 | dol_syslog('', 0, -1); |
||
| 194 | if ($this->transaction_opened <= 1) { |
||
| 195 | $ret = $this->query("ROLLBACK"); |
||
| 196 | $this->transaction_opened = 0; |
||
| 197 | dol_syslog("ROLLBACK Transaction".($log ? ' '.$log : ''), LOG_DEBUG); |
||
| 198 | return $ret; |
||
| 199 | } else { |
||
| 200 | $this->transaction_opened--; |
||
| 201 | return 1; |
||
| 202 | } |
||
| 203 | } |
||
| 204 | |||
| 205 | /** |
||
| 206 | * Define limits and offset of request |
||
| 207 | * |
||
| 208 | * @param int $limit Maximum number of lines returned (-1=conf->liste_limit, 0=no limit) |
||
| 209 | * @param int $offset Numero of line from where starting fetch |
||
| 210 | * @return string String with SQL syntax to add a limit and offset |
||
| 211 | */ |
||
| 212 | public function plimit($limit = 0, $offset = 0) |
||
| 213 | { |
||
| 214 | global $conf; |
||
| 215 | if (empty($limit)) { |
||
| 216 | return ""; |
||
| 217 | } |
||
| 218 | if ($limit < 0) { |
||
| 219 | $limit = $conf->liste_limit; |
||
| 220 | } |
||
| 221 | if ($offset > 0) { |
||
| 222 | return " LIMIT ".((int) $offset).",".((int) $limit)." "; |
||
| 223 | } else { |
||
| 224 | return " LIMIT ".((int) $limit)." "; |
||
| 225 | } |
||
| 226 | } |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Return version of database server into an array |
||
| 230 | * |
||
| 231 | * @return array Version array |
||
| 232 | */ |
||
| 233 | public function getVersionArray() |
||
| 234 | { |
||
| 235 | return preg_split("/[\.,-]/", $this->getVersion()); |
||
| 236 | } |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Return last request executed with query() |
||
| 240 | * |
||
| 241 | * @return string Last query |
||
| 242 | */ |
||
| 243 | public function lastquery() |
||
| 244 | { |
||
| 245 | return $this->lastquery; |
||
| 246 | } |
||
| 247 | |||
| 248 | /** |
||
| 249 | * Define sort criteria of request |
||
| 250 | * |
||
| 251 | * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb' |
||
| 252 | * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC'. Note: If the quantity fo sortorder values is lower than sortfield, we used the last value for missing values. |
||
| 253 | * @return string String to provide syntax of a sort sql string |
||
| 254 | */ |
||
| 255 | public function order($sortfield = null, $sortorder = null) |
||
| 256 | { |
||
| 257 | if (!empty($sortfield)) { |
||
| 258 | $oldsortorder = ''; |
||
| 259 | $return = ''; |
||
| 260 | $fields = explode(',', $sortfield); |
||
| 261 | $orders = explode(',', $sortorder); |
||
| 262 | $i = 0; |
||
| 263 | foreach ($fields as $val) { |
||
| 264 | if (!$return) { |
||
| 265 | $return .= ' ORDER BY '; |
||
| 266 | } else { |
||
| 267 | $return .= ', '; |
||
| 268 | } |
||
| 269 | |||
| 270 | $return .= preg_replace('/[^0-9a-z_\.]/i', '', $val); // Add field |
||
| 271 | |||
| 272 | $tmpsortorder = (empty($orders[$i]) ? '' : trim($orders[$i])); |
||
| 273 | |||
| 274 | // Only ASC and DESC values are valid SQL |
||
| 275 | if (strtoupper($tmpsortorder) === 'ASC') { |
||
| 276 | $oldsortorder = 'ASC'; |
||
| 277 | $return .= ' ASC'; |
||
| 278 | } elseif (strtoupper($tmpsortorder) === 'DESC') { |
||
| 279 | $oldsortorder = 'DESC'; |
||
| 280 | $return .= ' DESC'; |
||
| 281 | } else { |
||
| 282 | $return .= ' '.($oldsortorder ? $oldsortorder : 'ASC'); |
||
| 283 | } |
||
| 284 | |||
| 285 | $i++; |
||
| 286 | } |
||
| 287 | return $return; |
||
| 288 | } else { |
||
| 289 | return ''; |
||
| 290 | } |
||
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * Return last error label |
||
| 295 | * |
||
| 296 | * @return string Last error |
||
| 297 | */ |
||
| 298 | public function lasterror() |
||
| 301 | } |
||
| 302 | |||
| 303 | /** |
||
| 304 | * Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true) |
||
| 305 | * 19700101020000 -> 3600 with TZ+1 and gmt=0 |
||
| 306 | * 19700101020000 -> 7200 whaterver is TZ if gmt=1 |
||
| 307 | * |
||
| 308 | * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS) |
||
| 309 | * @param mixed $gm 'gmt'=Input informations are GMT values, 'tzserver'=Local to server TZ |
||
| 310 | * @return int|string Date TMS or '' |
||
| 311 | */ |
||
| 312 | public function jdate($string, $gm = 'tzserver') |
||
| 313 | { |
||
| 314 | // TODO $string should be converted into a GMT timestamp, so param gm should be set to true by default instead of false |
||
| 315 | if ($string == 0 || $string == "0000-00-00 00:00:00") { |
||
| 316 | return ''; |
||
| 317 | } |
||
| 318 | $string = preg_replace('/([^0-9])/i', '', $string); |
||
| 319 | $tmp = $string.'000000'; |
||
| 320 | $date = dol_mktime((int) substr($tmp, 8, 2), (int) substr($tmp, 10, 2), (int) substr($tmp, 12, 2), (int) substr($tmp, 4, 2), (int) substr($tmp, 6, 2), (int) substr($tmp, 0, 4), $gm); |
||
| 321 | return $date; |
||
| 322 | } |
||
| 323 | |||
| 324 | /** |
||
| 325 | * Return last query in error |
||
| 326 | * |
||
| 327 | * @return string lastqueryerror |
||
| 328 | */ |
||
| 329 | public function lastqueryerror() |
||
| 332 | } |
||
| 333 | |||
| 334 | /** |
||
| 335 | * Return first result from query as object |
||
| 336 | * Note : This method executes a given SQL query and retrieves the first row of results as an object. It should only be used with SELECT queries |
||
| 337 | * Dont add LIMIT to your query, it will be added by this method |
||
| 338 | * |
||
| 339 | * @param string $sql The sql query string |
||
| 340 | * @return bool|int|object False on failure, 0 on empty, object on success |
||
| 341 | */ |
||
| 342 | public function getRow($sql) |
||
| 357 | } |
||
| 358 | |||
| 359 | /** |
||
| 360 | * Return all results from query as an array of objects |
||
| 361 | * Note : This method executes a given SQL query and retrieves all row of results as an array of objects. It should only be used with SELECT queries |
||
| 362 | * be carefull with this method use it only with some limit of results to avoid performences loss. |
||
| 363 | * |
||
| 364 | * @param string $sql The sql query string |
||
| 365 | * @return bool|array Result |
||
| 366 | * @deprecated |
||
| 367 | */ |
||
| 368 | public function getRows($sql) |
||
| 382 | } |
||
| 383 | } |
||
| 384 |