Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Db 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 Db, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 53 | class Db |
||
| 54 | { |
||
| 55 | /** |
||
| 56 | * Fetchmode to fetch only as associative array with $colname => $value pairs |
||
| 57 | * |
||
| 58 | * Use the FETCH_* constants to be compatible, if we replace ADOdb ... |
||
| 59 | */ |
||
| 60 | const FETCH_ASSOC = ADODB_FETCH_ASSOC; |
||
| 61 | /** |
||
| 62 | * Fetchmode to fetch only as (numeric indexed) array: array($val1,$val2,...) |
||
| 63 | */ |
||
| 64 | const FETCH_NUM = ADODB_FETCH_NUM; |
||
| 65 | /** |
||
| 66 | * Fetchmode to have both numeric and column-name indexes |
||
| 67 | */ |
||
| 68 | const FETCH_BOTH = ADODB_FETCH_BOTH; |
||
| 69 | /** |
||
| 70 | * @var string $type translated database type: mysqlt+mysqli ==> mysql, same for odbc-types |
||
| 71 | */ |
||
| 72 | var $Type = ''; |
||
| 73 | |||
| 74 | /** |
||
| 75 | * @var string $type database type as defined in the header.inc.php, eg. mysqlt |
||
| 76 | */ |
||
| 77 | var $setupType = ''; |
||
| 78 | |||
| 79 | /** |
||
| 80 | * @var string $Host database host to connect to |
||
| 81 | */ |
||
| 82 | var $Host = ''; |
||
| 83 | |||
| 84 | /** |
||
| 85 | * @var string $Port port number of database to connect to |
||
| 86 | */ |
||
| 87 | var $Port = ''; |
||
| 88 | |||
| 89 | /** |
||
| 90 | * @var string $Database name of database to use |
||
| 91 | */ |
||
| 92 | var $Database = ''; |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @var string $User name of database user |
||
| 96 | */ |
||
| 97 | var $User = ''; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * @var string $Password password for database user |
||
| 101 | */ |
||
| 102 | var $Password = ''; |
||
| 103 | |||
| 104 | /** |
||
| 105 | * @var boolean $readonly only allow readonly access to database |
||
| 106 | */ |
||
| 107 | var $readonly = false; |
||
| 108 | |||
| 109 | /** |
||
| 110 | * @var int $Debug enable debuging - 0 no, 1 yes |
||
| 111 | */ |
||
| 112 | var $Debug = 0; |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Log update querys to error_log |
||
| 116 | * |
||
| 117 | * @var boolean |
||
| 118 | */ |
||
| 119 | var $log_updates = false; |
||
| 120 | |||
| 121 | /** |
||
| 122 | * @var array $Record current record |
||
| 123 | */ |
||
| 124 | var $Record = array(); |
||
| 125 | |||
| 126 | /** |
||
| 127 | * @var int row number for current record |
||
| 128 | */ |
||
| 129 | var $Row; |
||
| 130 | |||
| 131 | /** |
||
| 132 | * @var int $Errno internal rdms error number for last error |
||
| 133 | */ |
||
| 134 | var $Errno = 0; |
||
| 135 | |||
| 136 | /** |
||
| 137 | * @var string descriptive text from last error |
||
| 138 | */ |
||
| 139 | var $Error = ''; |
||
| 140 | |||
| 141 | /** |
||
| 142 | * eGW's own query log, independent of the db-type, eg. /tmp/query.log |
||
| 143 | * |
||
| 144 | * @var string |
||
| 145 | */ |
||
| 146 | var $query_log; |
||
| 147 | |||
| 148 | /** |
||
| 149 | * ADOdb connection |
||
| 150 | * |
||
| 151 | * @var ADOConnection |
||
| 152 | */ |
||
| 153 | var $Link_ID = 0; |
||
| 154 | /** |
||
| 155 | * ADOdb connection |
||
| 156 | * |
||
| 157 | * @var ADOConnection |
||
| 158 | */ |
||
| 159 | var $privat_Link_ID = False; // do we use a privat Link_ID or a reference to the global ADOdb object |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Can be used to transparently convert tablenames, eg. 'mytable' => 'otherdb.othertable' |
||
| 163 | * |
||
| 164 | * Can be set eg. at the *end* of header.inc.php. |
||
| 165 | * Only works with new Api\Db methods (select, insert, update, delete) not query! |
||
| 166 | * |
||
| 167 | * @var array |
||
| 168 | */ |
||
| 169 | static $tablealiases = array(); |
||
| 170 | |||
| 171 | /** |
||
| 172 | * Callback to check if selected node is healty / should be used |
||
| 173 | * |
||
| 174 | * @var callback throwing Db\Exception\Connection, if connected node should NOT be used |
||
| 175 | */ |
||
| 176 | static $health_check; |
||
| 177 | |||
| 178 | /** |
||
| 179 | * db allows sub-queries, true for everything but mysql < 4.1 |
||
| 180 | * |
||
| 181 | * use like: if ($db->capabilities[self::CAPABILITY_SUB_QUERIES]) ... |
||
| 182 | */ |
||
| 183 | const CAPABILITY_SUB_QUERIES = 'sub_queries'; |
||
| 184 | /** |
||
| 185 | * db allows union queries, true for everything but mysql < 4.0 |
||
| 186 | */ |
||
| 187 | const CAPABILITY_UNION = 'union'; |
||
| 188 | /** |
||
| 189 | * db allows an outer join, will be set eg. for postgres |
||
| 190 | */ |
||
| 191 | const CAPABILITY_OUTER_JOIN = 'outer_join'; |
||
| 192 | /** |
||
| 193 | * db is able to use DISTINCT on text or blob columns |
||
| 194 | */ |
||
| 195 | const CAPABILITY_DISTINCT_ON_TEXT = 'distinct_on_text'; |
||
| 196 | /** |
||
| 197 | * DB is able to use LIKE on text columns |
||
| 198 | */ |
||
| 199 | const CAPABILITY_LIKE_ON_TEXT = 'like_on_text'; |
||
| 200 | /** |
||
| 201 | * DB allows ORDER on text columns |
||
| 202 | * |
||
| 203 | * boolean or string for sprintf for a cast (eg. 'CAST(%s AS varchar) |
||
| 204 | */ |
||
| 205 | const CAPABILITY_ORDER_ON_TEXT = 'order_on_text'; |
||
| 206 | /** |
||
| 207 | * case of returned column- and table-names: upper, lower(pgSql), preserv(MySQL) |
||
| 208 | */ |
||
| 209 | const CAPABILITY_NAME_CASE = 'name_case'; |
||
| 210 | /** |
||
| 211 | * does DB supports a changeable client-encoding |
||
| 212 | */ |
||
| 213 | const CAPABILITY_CLIENT_ENCODING = 'client_encoding'; |
||
| 214 | /** |
||
| 215 | * case insensitiv like statement (in $db->capabilities[self::CAPABILITY_CASE_INSENSITIV_LIKE]), default LIKE, ILIKE for postgres |
||
| 216 | */ |
||
| 217 | const CAPABILITY_CASE_INSENSITIV_LIKE = 'case_insensitive_like'; |
||
| 218 | /** |
||
| 219 | * DB requires varchar columns to be truncated to the max. size (eg. Postgres) |
||
| 220 | */ |
||
| 221 | const CAPABILITY_REQUIRE_TRUNCATE_VARCHAR = 'require_truncate_varchar'; |
||
| 222 | /** |
||
| 223 | * How to cast a column to varchar: CAST(%s AS varchar) |
||
| 224 | * |
||
| 225 | * MySQL requires to use CAST(%s AS char)! |
||
| 226 | * |
||
| 227 | * Use as: $sql = sprintf($GLOBALS['egw']->db->capabilities[self::CAPABILITY_CAST_AS_VARCHAR],$expression); |
||
| 228 | */ |
||
| 229 | const CAPABILITY_CAST_AS_VARCHAR = 'cast_as_varchar'; |
||
| 230 | /** |
||
| 231 | * default capabilities will be changed by method set_capabilities($ado_driver,$db_version) |
||
| 232 | * |
||
| 233 | * should be used with the CAPABILITY_* constants as key |
||
| 234 | * |
||
| 235 | * @var array |
||
| 236 | */ |
||
| 237 | var $capabilities = array( |
||
| 238 | self::CAPABILITY_SUB_QUERIES => true, |
||
| 239 | self::CAPABILITY_UNION => true, |
||
| 240 | self::CAPABILITY_OUTER_JOIN => false, |
||
| 241 | self::CAPABILITY_DISTINCT_ON_TEXT => true, |
||
| 242 | self::CAPABILITY_LIKE_ON_TEXT => true, |
||
| 243 | self::CAPABILITY_ORDER_ON_TEXT => true, |
||
| 244 | self::CAPABILITY_NAME_CASE => 'upper', |
||
| 245 | self::CAPABILITY_CLIENT_ENCODING => false, |
||
| 246 | self::CAPABILITY_CASE_INSENSITIV_LIKE => 'LIKE', |
||
| 247 | self::CAPABILITY_REQUIRE_TRUNCATE_VARCHAR => true, |
||
| 248 | self::CAPABILITY_CAST_AS_VARCHAR => 'CAST(%s AS varchar)', |
||
| 249 | ); |
||
| 250 | |||
| 251 | var $prepared_sql = array(); // sql is the index |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Constructor |
||
| 255 | * |
||
| 256 | * @param array $db_data =null values for keys 'db_name', 'db_host', 'db_port', 'db_user', 'db_pass', 'db_type', 'db_readonly' |
||
| 257 | */ |
||
| 258 | function __construct(array $db_data=null) |
||
| 277 | |||
| 278 | /** |
||
| 279 | * @param string $query query to be executed (optional) |
||
| 280 | */ |
||
| 281 | |||
| 282 | function db($query = '') |
||
| 286 | |||
| 287 | /** |
||
| 288 | * @return int current connection id |
||
| 289 | */ |
||
| 290 | function link_id() |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Open a connection to a database |
||
| 297 | * |
||
| 298 | * @param string $Database name of database to use (optional) |
||
| 299 | * @param string $Host database host to connect to (optional) |
||
| 300 | * @param string $Port database port to connect to (optional) |
||
| 301 | * @param string $User name of database user (optional) |
||
| 302 | * @param string $Password password for database user (optional) |
||
| 303 | * @param string $Type type of database (optional) |
||
| 304 | * @throws Db\Exception\Connection |
||
| 305 | * @return ADOConnection |
||
| 306 | */ |
||
| 307 | function connect($Database = NULL, $Host = NULL, $Port = NULL, $User = NULL, $Password = NULL, $Type = NULL) |
||
| 368 | |||
| 369 | /** |
||
| 370 | * Check if just connected Galera cluster node is healthy / fully operational |
||
| 371 | * |
||
| 372 | * A node in state "Donor/Desynced" will block updates at the end of a SST. |
||
| 373 | * Therefore we try to avoid that node, if we have an alternative. |
||
| 374 | * |
||
| 375 | * To enable this check add the following to your header.inc.php: |
||
| 376 | * |
||
| 377 | * require_once(EGW_INCLUDE_ROOT.'/api/src/Db.php'); |
||
| 378 | * EGroupware\Api\Db::$health_check = array('EGroupware\Api\Db', 'galera_cluster_health'); |
||
| 379 | * |
||
| 380 | * @param Api\Db $db already connected Api\Db instance to check |
||
| 381 | * @throws Db\Exception\Connection if node should NOT be used |
||
| 382 | */ |
||
| 383 | static function galera_cluster_health(Db $db) |
||
| 397 | |||
| 398 | /** |
||
| 399 | * Get one of multiple (semicolon-separated) DB-hosts to use |
||
| 400 | * |
||
| 401 | * Which host to use is cached in session, default is first one. |
||
| 402 | * |
||
| 403 | * @param boolean $next =false true: move to next host |
||
| 404 | * @return boolean|string hostname or false, if already number-of-hosts plus 2 times called with $next == true |
||
| 405 | */ |
||
| 406 | public function get_host($next = false) |
||
| 425 | |||
| 426 | /** |
||
| 427 | * Connect to given host |
||
| 428 | * |
||
| 429 | * @param string $Host host to connect to |
||
| 430 | * @return ADOConnection |
||
| 431 | * @throws Db\Exception\Connection |
||
| 432 | */ |
||
| 433 | protected function _connect($Host) |
||
| 596 | |||
| 597 | /** |
||
| 598 | * Magic method to re-connect with the database, if the object get's restored from the session |
||
| 599 | */ |
||
| 600 | function __wakeup() |
||
| 604 | |||
| 605 | /** |
||
| 606 | * Magic method called when object get's serialized |
||
| 607 | * |
||
| 608 | * We do NOT store Link_ID and private_Link_ID, as we need to reconnect anyway. |
||
| 609 | * This also ensures reevaluating environment-data or multiple hosts in connection-data! |
||
| 610 | * |
||
| 611 | * @return array |
||
| 612 | */ |
||
| 613 | function __sleep() |
||
| 621 | |||
| 622 | /** |
||
| 623 | * changes defaults set in class-var $capabilities depending on db-type and -version |
||
| 624 | * |
||
| 625 | * @param string $adodb_driver mysql, postgres, mssql, sapdb, oci8 |
||
| 626 | * @param string $db_version version-number of connected db-server, as reported by ServerInfo |
||
| 627 | */ |
||
| 628 | function set_capabilities($adodb_driver,$db_version) |
||
| 664 | |||
| 665 | /** |
||
| 666 | * Close a connection to a database |
||
| 667 | */ |
||
| 668 | function disconnect() |
||
| 679 | |||
| 680 | /** |
||
| 681 | * Convert a unix timestamp to a rdms specific timestamp |
||
| 682 | * |
||
| 683 | * @param int unix timestamp |
||
| 684 | * @return string rdms specific timestamp |
||
| 685 | */ |
||
| 686 | function to_timestamp($epoch) |
||
| 695 | |||
| 696 | /** |
||
| 697 | * Convert a rdms specific timestamp to a unix timestamp |
||
| 698 | * |
||
| 699 | * @param string rdms specific timestamp |
||
| 700 | * @return int unix timestamp |
||
| 701 | */ |
||
| 702 | function from_timestamp($timestamp) |
||
| 710 | |||
| 711 | /** |
||
| 712 | * convert a rdbms specific boolean value |
||
| 713 | * |
||
| 714 | * @param string $val boolean value in db-specfic notation |
||
| 715 | * @return boolean |
||
| 716 | */ |
||
| 717 | public static function from_bool($val) |
||
| 721 | |||
| 722 | /** |
||
| 723 | * Execute a query |
||
| 724 | * |
||
| 725 | * @param string $Query_String the query to be executed |
||
| 726 | * @param int $line the line method was called from - use __LINE__ |
||
| 727 | * @param string $file the file method was called from - use __FILE__ |
||
| 728 | * @param int $offset row to start from, default 0 |
||
| 729 | * @param int $num_rows number of rows to return (optional), default -1 = all, 0 will use $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'] |
||
| 730 | * @param array|boolean $inputarr array for binding variables to parameters or false (default) |
||
| 731 | * @param int $fetchmode =self::FETCH_BOTH self::FETCH_BOTH (default), self::FETCH_ASSOC or self::FETCH_NUM |
||
| 732 | * @param boolean $reconnect =true true: try reconnecting if server closes connection, false: dont (mysql only!) |
||
| 733 | * @return ADORecordSet or false, if the query fails |
||
| 734 | * @throws Db\Exception\InvalidSql with $this->Link_ID->ErrorNo() as code |
||
| 735 | */ |
||
| 736 | function query($Query_String, $line = '', $file = '', $offset=0, $num_rows=-1, $inputarr=false, $fetchmode=self::FETCH_BOTH, $reconnect=true) |
||
| 798 | |||
| 799 | /** |
||
| 800 | * Execute a query with limited result set |
||
| 801 | * |
||
| 802 | * @param string $Query_String the query to be executed |
||
| 803 | * @param int $offset row to start from, default 0 |
||
| 804 | * @param int $line the line method was called from - use __LINE__ |
||
| 805 | * @param string $file the file method was called from - use __FILE__ |
||
| 806 | * @param int $num_rows number of rows to return (optional), default -1 = all, 0 will use $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'] |
||
| 807 | * @param array|boolean $inputarr array for binding variables to parameters or false (default) |
||
| 808 | * @return ADORecordSet or false, if the query fails |
||
| 809 | */ |
||
| 810 | function limit_query($Query_String, $offset, $line = '', $file = '', $num_rows = '',$inputarr=false) |
||
| 814 | |||
| 815 | /** |
||
| 816 | * Begin Transaction |
||
| 817 | * |
||
| 818 | * @return int/boolean current transaction-id, of false if no connection |
||
| 819 | */ |
||
| 820 | function transaction_begin() |
||
| 829 | |||
| 830 | /** |
||
| 831 | * Complete the transaction |
||
| 832 | * |
||
| 833 | * @return bool True if sucessful, False if fails |
||
| 834 | */ |
||
| 835 | function transaction_commit() |
||
| 844 | |||
| 845 | /** |
||
| 846 | * Rollback the current transaction |
||
| 847 | * |
||
| 848 | * @return bool True if sucessful, False if fails |
||
| 849 | */ |
||
| 850 | function transaction_abort() |
||
| 859 | |||
| 860 | /** |
||
| 861 | * Lock a rows in table |
||
| 862 | * |
||
| 863 | * Will escalate and lock the table if row locking not supported. |
||
| 864 | * Will normally free the lock at the end of the transaction. |
||
| 865 | * |
||
| 866 | * @param string $table name of table to lock |
||
| 867 | * @param string $where ='true' where clause to use, eg: "WHERE row=12". Defaults to lock whole table. |
||
| 868 | * @param string $col ='1 as adodbignore' |
||
| 869 | */ |
||
| 870 | View Code Duplication | function row_lock($table, $where='true', $col='1 as adodbignore') |
|
| 883 | |||
| 884 | /** |
||
| 885 | * Commit changed rows in table |
||
| 886 | * |
||
| 887 | * @param string $table |
||
| 888 | * @return boolean |
||
| 889 | */ |
||
| 890 | View Code Duplication | function commit_lock($table) |
|
| 903 | |||
| 904 | /** |
||
| 905 | * Unlock rows in table |
||
| 906 | * |
||
| 907 | * @param string $table |
||
| 908 | * @return boolean |
||
| 909 | */ |
||
| 910 | View Code Duplication | function rollback_lock($table) |
|
| 923 | |||
| 924 | /** |
||
| 925 | * Find the primary key of the last insertion on the current db connection |
||
| 926 | * |
||
| 927 | * @param string $table name of table the insert was performed on |
||
| 928 | * @param string $field the autoincrement primary key of the table |
||
| 929 | * @return int the id, -1 if fails |
||
| 930 | */ |
||
| 931 | function get_last_insert_id($table, $field) |
||
| 951 | |||
| 952 | /** |
||
| 953 | * Get the number of rows affected by last update or delete |
||
| 954 | * |
||
| 955 | * @return int number of rows |
||
| 956 | */ |
||
| 957 | function affected_rows() |
||
| 967 | |||
| 968 | /** |
||
| 969 | * Get description of a table |
||
| 970 | * |
||
| 971 | * Beside the column-name all other data depends on the db-type !!! |
||
| 972 | * |
||
| 973 | * @param string $table name of table to describe |
||
| 974 | * @param bool $full optional, default False summary information, True full information |
||
| 975 | * @return array table meta data |
||
| 976 | */ |
||
| 977 | function metadata($table='',$full=false) |
||
| 1023 | |||
| 1024 | /** |
||
| 1025 | * Get a list of table names in the current database |
||
| 1026 | * |
||
| 1027 | * @param boolean $just_name =false true return array of table-names, false return old format |
||
| 1028 | * @return array list of the tables |
||
| 1029 | */ |
||
| 1030 | function table_names($just_name=false) |
||
| 1056 | |||
| 1057 | /** |
||
| 1058 | * Return a list of indexes in current database |
||
| 1059 | * |
||
| 1060 | * @return array list of indexes |
||
| 1061 | */ |
||
| 1062 | function index_names() |
||
| 1080 | |||
| 1081 | /** |
||
| 1082 | * Returns an array containing column names that are the primary keys of $tablename. |
||
| 1083 | * |
||
| 1084 | * @return array of columns |
||
| 1085 | */ |
||
| 1086 | function pkey_columns($tablename) |
||
| 1094 | |||
| 1095 | /** |
||
| 1096 | * Create a new database |
||
| 1097 | * |
||
| 1098 | * @param string $adminname name of database administrator user (optional) |
||
| 1099 | * @param string $adminpasswd password for the database administrator user (optional) |
||
| 1100 | * @param string $charset default charset for the database |
||
| 1101 | * @param string $grant_host ='localhost' host/ip of the webserver |
||
| 1102 | */ |
||
| 1103 | function create_database($adminname = '', $adminpasswd = '', $charset='', $grant_host='localhost') |
||
| 1149 | |||
| 1150 | /** |
||
| 1151 | * concat a variable number of strings together, to be used in a query |
||
| 1152 | * |
||
| 1153 | * Example: $db->concat($db->quote('Hallo '),'username') would return |
||
| 1154 | * for mysql "concat('Hallo ',username)" or "'Hallo ' || username" for postgres |
||
| 1155 | * @param string $str1 already quoted stringliteral or column-name, variable number of arguments |
||
| 1156 | * @return string to be used in a query |
||
| 1157 | */ |
||
| 1158 | function concat(/*$str1, ...*/) |
||
| 1168 | |||
| 1169 | /** |
||
| 1170 | * Concat grouped values of an expression with optional order and separator |
||
| 1171 | * |
||
| 1172 | * @param string $expr column-name or expression optional prefixed with "DISTINCT" |
||
| 1173 | * @param string $order_by ='' optional order |
||
| 1174 | * @param string $separator =',' optional separator, default is comma |
||
| 1175 | * @return string|boolean false if not supported by dbms |
||
| 1176 | */ |
||
| 1177 | function group_concat($expr, $order_by='', $separator=',') |
||
| 1203 | |||
| 1204 | /** |
||
| 1205 | * SQL returning character (not byte!) positions for $substr in $str |
||
| 1206 | * |
||
| 1207 | * @param string $str |
||
| 1208 | * @param string $substr |
||
| 1209 | * @return string SQL returning character (not byte!) positions for $substr in $str |
||
| 1210 | */ |
||
| 1211 | function strpos($str, $substr) |
||
| 1224 | |||
| 1225 | /** |
||
| 1226 | * Convert a DB specific timestamp in a unix timestamp stored as integer, like MySQL: UNIX_TIMESTAMP(ts) |
||
| 1227 | * |
||
| 1228 | * @param string $expr name of an integer column or integer expression |
||
| 1229 | * @return string SQL expression of type timestamp |
||
| 1230 | */ |
||
| 1231 | function unix_timestamp($expr) |
||
| 1245 | |||
| 1246 | /** |
||
| 1247 | * Convert a unix timestamp stored as integer in the db into a db timestamp, like MySQL: FROM_UNIXTIME(ts) |
||
| 1248 | * |
||
| 1249 | * @param string $expr name of an integer column or integer expression |
||
| 1250 | * @return string SQL expression of type timestamp |
||
| 1251 | */ |
||
| 1252 | function from_unixtime($expr) |
||
| 1267 | |||
| 1268 | /** |
||
| 1269 | * format a timestamp as string, like MySQL: DATE_FORMAT(ts) |
||
| 1270 | * |
||
| 1271 | * Please note: only a subset of the MySQL formats are implemented |
||
| 1272 | * |
||
| 1273 | * @param string $expr name of a timestamp column or timestamp expression |
||
| 1274 | * @param string $format format specifier like '%Y-%m-%d %H:%i:%s' or '%V%X' ('%v%x') weeknumber & year with Sunday (Monday) as first day |
||
| 1275 | * @return string SQL expression of type timestamp |
||
| 1276 | */ |
||
| 1277 | function date_format($expr,$format) |
||
| 1304 | |||
| 1305 | /** |
||
| 1306 | * Cast a column or sql expression to integer, necessary at least for postgreSQL or MySQL for sorting |
||
| 1307 | * |
||
| 1308 | * @param string $expr |
||
| 1309 | * @return string |
||
| 1310 | */ |
||
| 1311 | function to_double($expr) |
||
| 1322 | |||
| 1323 | /** |
||
| 1324 | * Cast a column or sql expression to integer, necessary at least for postgreSQL |
||
| 1325 | * |
||
| 1326 | * @param string $expr |
||
| 1327 | * @return string |
||
| 1328 | */ |
||
| 1329 | function to_int($expr) |
||
| 1340 | |||
| 1341 | /** |
||
| 1342 | * Cast a column or sql expression to varchar, necessary at least for postgreSQL |
||
| 1343 | * |
||
| 1344 | * @param string $expr |
||
| 1345 | * @return string |
||
| 1346 | */ |
||
| 1347 | function to_varchar($expr) |
||
| 1356 | |||
| 1357 | /** |
||
| 1358 | * Correctly Quote Identifiers like table- or colmnnames for use in SQL-statements |
||
| 1359 | * |
||
| 1360 | * This is mostly copy & paste from adodb's datadict class |
||
| 1361 | * @param string $_name |
||
| 1362 | * @return string quoted string |
||
| 1363 | */ |
||
| 1364 | function name_quote($_name = NULL) |
||
| 1400 | |||
| 1401 | /** |
||
| 1402 | * Escape values before sending them to the database - prevents SQL injection and SQL errors ;-) |
||
| 1403 | * |
||
| 1404 | * Please note that the quote function already returns necessary quotes: quote('Hello') === "'Hello'". |
||
| 1405 | * Int and Auto types are casted to int: quote('1','int') === 1, quote('','int') === 0, quote('Hello','int') === 0 |
||
| 1406 | * Arrays of id's stored in strings: quote(array(1,2,3),'string') === "'1,2,3'" |
||
| 1407 | * |
||
| 1408 | * @param mixed $value the value to be escaped |
||
| 1409 | * @param string|boolean $type =false string the type of the db-column, default False === varchar |
||
| 1410 | * @param boolean $not_null =true is column NOT NULL, default true, else php null values are written as SQL NULL |
||
| 1411 | * @param int $length =null length of the varchar column, to truncate it if the database requires it (eg. Postgres) |
||
| 1412 | * @param string $glue =',' used to glue array values together for the string type |
||
| 1413 | * @return string escaped sting |
||
| 1414 | */ |
||
| 1415 | function quote($value,$type=False,$not_null=true,$length=null,$glue=',') |
||
| 1493 | |||
| 1494 | /** |
||
| 1495 | * Implodes an array of column-value pairs for the use in sql-querys. |
||
| 1496 | * All data is run through quote (does either addslashes() or (int)) - prevents SQL injunction and SQL errors ;-). |
||
| 1497 | * |
||
| 1498 | * @author RalfBecker<at>outdoor-training.de |
||
| 1499 | * |
||
| 1500 | * @param string $glue in most cases this will be either ',' or ' AND ', depending you your query |
||
| 1501 | * @param array $array column-name / value pairs, if the value is an array all its array-values will be quoted |
||
| 1502 | * according to the type of the column, and the whole array with be formatted like (val1,val2,...) |
||
| 1503 | * If $use_key == True, an ' IN ' instead a '=' is used. Good for category- or user-lists. |
||
| 1504 | * If the key is numerical (no key given in the array-definition) the value is used as is, eg. |
||
| 1505 | * array('visits=visits+1') gives just "visits=visits+1" (no quoting at all !!!) |
||
| 1506 | * @param boolean|string $use_key If $use_key===True a "$key=" prefix each value (default), typically set to False |
||
| 1507 | * or 'VALUES' for insert querys, on 'VALUES' "(key1,key2,...) VALUES (val1,val2,...)" is returned |
||
| 1508 | * @param array|boolean $only if set to an array only colums which are set (as data !!!) are written |
||
| 1509 | * typicaly used to form a WHERE-clause from the primary keys. |
||
| 1510 | * If set to True, only columns from the colum_definitons are written. |
||
| 1511 | * @param array|boolean $column_definitions this can be set to the column-definitions-array |
||
| 1512 | * of your table ($tables_baseline[$table]['fd'] of the setup/tables_current.inc.php file). |
||
| 1513 | * If its set, the column-type-data determinates if (int) or addslashes is used. |
||
| 1514 | * @return string SQL |
||
| 1515 | */ |
||
| 1516 | function column_data_implode($glue,$array,$use_key=True,$only=False,$column_definitions=False) |
||
| 1599 | |||
| 1600 | /** |
||
| 1601 | * Sets the default column-definitions for use with column_data_implode() |
||
| 1602 | * |
||
| 1603 | * @author RalfBecker<at>outdoor-training.de |
||
| 1604 | * |
||
| 1605 | * @param array|boolean $column_definitions this can be set to the column-definitions-array |
||
| 1606 | * of your table ($tables_baseline[$table]['fd'] of the setup/tables_current.inc.php file). |
||
| 1607 | * If its set, the column-type-data determinates if (int) or addslashes is used. |
||
| 1608 | */ |
||
| 1609 | function set_column_definitions($column_definitions=False) |
||
| 1613 | |||
| 1614 | /** |
||
| 1615 | * Application name used by the API |
||
| 1616 | * |
||
| 1617 | */ |
||
| 1618 | const API_APPNAME = 'api'; |
||
| 1619 | /** |
||
| 1620 | * Default app, if no app specified in select, insert, delete, ... |
||
| 1621 | * |
||
| 1622 | * @var string |
||
| 1623 | */ |
||
| 1624 | private $app=self::API_APPNAME; |
||
| 1625 | |||
| 1626 | /** |
||
| 1627 | * Sets the application in which the db-class looks for table-defintions |
||
| 1628 | * |
||
| 1629 | * Used by table_definitions, insert, update, select, expression and delete. If the app is not set via set_app, |
||
| 1630 | * it need to be set for these functions on every call |
||
| 1631 | * |
||
| 1632 | * @param string $app the app-name |
||
| 1633 | */ |
||
| 1634 | function set_app($app) |
||
| 1646 | |||
| 1647 | /** |
||
| 1648 | * reads the table-definitions from the app's setup/tables_current.inc.php file |
||
| 1649 | * |
||
| 1650 | * The already read table-definitions are shared between all db-instances via a static var. |
||
| 1651 | * |
||
| 1652 | * @author RalfBecker<at>outdoor-training.de |
||
| 1653 | * |
||
| 1654 | * @param bool|string $app name of the app or default False to use the app set by db::set_app or the current app, |
||
| 1655 | * true to search the already loaded table-definitions for $table and then search all existing apps for it |
||
| 1656 | * @param bool|string $table if set return only defintions of that table, else return all defintions |
||
| 1657 | * @return mixed array with table-defintions or False if file not found |
||
| 1658 | */ |
||
| 1659 | function get_table_definitions($app=False,$table=False) |
||
| 1726 | |||
| 1727 | /** |
||
| 1728 | * Get specified attribute (default comment) of a colum or whole definition (if $attribute === null) |
||
| 1729 | * |
||
| 1730 | * Can be used static, in which case the global db object is used ($GLOBALS['egw']->db) and $app should be specified |
||
| 1731 | * |
||
| 1732 | * @param string $column name of column |
||
| 1733 | * @param string $table name of table |
||
| 1734 | * @param string $app=null app name or NULL to use $this->app, set via self::set_app() |
||
| 1735 | * @param string $attribute='comment' what field to return, NULL for array with all fields, default 'comment' to return the comment |
||
| 1736 | * @return string|array NULL if table or column or attribute not found |
||
| 1737 | */ |
||
| 1738 | /* static */ function get_column_attribute($column,$table,$app=null,$attribute='comment') |
||
| 1752 | |||
| 1753 | /** |
||
| 1754 | * Insert a row of data into a table or updates it if $where is given, all data is quoted according to it's type |
||
| 1755 | * |
||
| 1756 | * @author RalfBecker<at>outdoor-training.de |
||
| 1757 | * |
||
| 1758 | * @param string $table name of the table |
||
| 1759 | * @param array $data with column-name / value pairs |
||
| 1760 | * @param mixed $where string with where clause or array with column-name / values pairs to check if a row with that keys already exists, or false for an unconditional insert |
||
| 1761 | * if the row exists db::update is called else a new row with $date merged with $where gets inserted (data has precedence) |
||
| 1762 | * @param int $line line-number to pass to query |
||
| 1763 | * @param string $file file-name to pass to query |
||
| 1764 | * @param string|boolean $app string with name of app or False to use the current-app |
||
| 1765 | * @param bool $use_prepared_statement use a prepared statement |
||
| 1766 | * @param array|bool $table_def use this table definition. If False, the table definition will be read from tables_baseline |
||
| 1767 | * @return ADORecordSet or false, if the query fails |
||
| 1768 | */ |
||
| 1769 | function insert($table,$data,$where,$line,$file,$app=False,$use_prepared_statement=false,$table_def=False) |
||
| 1862 | |||
| 1863 | /** |
||
| 1864 | * Updates the data of one or more rows in a table, all data is quoted according to it's type |
||
| 1865 | * |
||
| 1866 | * @author RalfBecker<at>outdoor-training.de |
||
| 1867 | * |
||
| 1868 | * @param string $table name of the table |
||
| 1869 | * @param array $data with column-name / value pairs |
||
| 1870 | * @param array $where column-name / values pairs and'ed together for the where clause |
||
| 1871 | * @param int $line line-number to pass to query |
||
| 1872 | * @param string $file file-name to pass to query |
||
| 1873 | * @param string|boolean $app string with name of app or False to use the current-app |
||
| 1874 | * @param bool $use_prepared_statement use a prepared statement |
||
| 1875 | * @param array|bool $table_def use this table definition. If False, the table definition will be read from tables_baseline |
||
| 1876 | * @return ADORecordSet or false, if the query fails |
||
| 1877 | */ |
||
| 1878 | function update($table,$data,$where,$line,$file,$app=False,$use_prepared_statement=false,$table_def=False) |
||
| 1952 | |||
| 1953 | /** |
||
| 1954 | * Deletes one or more rows in table, all data is quoted according to it's type |
||
| 1955 | * |
||
| 1956 | * @author RalfBecker<at>outdoor-training.de |
||
| 1957 | * |
||
| 1958 | * @param string $table name of the table |
||
| 1959 | * @param array $where column-name / values pairs and'ed together for the where clause |
||
| 1960 | * @param int $line line-number to pass to query |
||
| 1961 | * @param string $file file-name to pass to query |
||
| 1962 | * @param string|boolean $app string with name of app or False to use the current-app |
||
| 1963 | * @param array|bool $table_def use this table definition. If False, the table definition will be read from tables_baseline |
||
| 1964 | * @return ADORecordSet or false, if the query fails |
||
| 1965 | */ |
||
| 1966 | function delete($table,$where,$line,$file,$app=False,$table_def=False) |
||
| 1979 | |||
| 1980 | /** |
||
| 1981 | * Formats and quotes a sql expression to be used eg. as where-clause |
||
| 1982 | * |
||
| 1983 | * The function has a variable number of arguments, from which the expession gets constructed |
||
| 1984 | * eg. db::expression('my_table','(',array('name'=>"test'ed",'lang'=>'en'),') OR ',array('owner'=>array('',4,10))) |
||
| 1985 | * gives "(name='test\'ed' AND lang='en') OR 'owner' IN (0,4,5,6,10)" if name,lang are strings and owner is an integer |
||
| 1986 | * |
||
| 1987 | * @param string|array $table_def table-name or definition array |
||
| 1988 | * @param mixed $args variable number of arguments of the following types: |
||
| 1989 | * string: get's as is into the result |
||
| 1990 | * array: column-name / value pairs: the value gets quoted according to the type of the column and prefixed |
||
| 1991 | * with column-name=, multiple pairs are AND'ed together, see db::column_data_implode |
||
| 1992 | * bool: If False or is_null($arg): the next 2 (!) arguments gets ignored |
||
| 1993 | * |
||
| 1994 | * Please note: As the function has a variable number of arguments, you CAN NOT add further parameters !!! |
||
| 1995 | * |
||
| 1996 | * @return string the expression generated from the arguments |
||
| 1997 | */ |
||
| 1998 | function expression($table_def/*,$args, ...*/) |
||
| 2029 | |||
| 2030 | /** |
||
| 2031 | * Selects one or more rows in table depending on where, all data is quoted according to it's type |
||
| 2032 | * |
||
| 2033 | * @author RalfBecker<at>outdoor-training.de |
||
| 2034 | * |
||
| 2035 | * @param string $table name of the table |
||
| 2036 | * @param array|string $cols string or array of column-names / select-expressions |
||
| 2037 | * @param array|string $where string or array with column-name / values pairs AND'ed together for the where clause |
||
| 2038 | * @param int $line line-number to pass to query |
||
| 2039 | * @param string $file file-name to pass to query |
||
| 2040 | * @param int|bool $offset offset for a limited query or False (default) |
||
| 2041 | * @param string $append string to append to the end of the query, eg. ORDER BY ... |
||
| 2042 | * @param string|boolean $app string with name of app or False to use the current-app |
||
| 2043 | * @param int $num_rows number of rows to return if offset set, default 0 = use default in user prefs |
||
| 2044 | * @param string $join =null sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or |
||
| 2045 | * "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join! |
||
| 2046 | * @param array|bool $table_def use this table definition. If False, the table definition will be read from tables_baseline |
||
| 2047 | * @param int $fetchmode =self::FETCH_ASSOC self::FETCH_ASSOC (default), self::FETCH_BOTH or self::FETCH_NUM |
||
| 2048 | * @return ADORecordSet or false, if the query fails |
||
| 2049 | */ |
||
| 2050 | function select($table,$cols,$where,$line,$file,$offset=False,$append='',$app=False,$num_rows=0,$join='',$table_def=False,$fetchmode=self::FETCH_ASSOC) |
||
| 2082 | |||
| 2083 | /** |
||
| 2084 | * Does a union over multiple selects |
||
| 2085 | * |
||
| 2086 | * @author RalfBecker<at>outdoor-training.de |
||
| 2087 | * |
||
| 2088 | * @param array $selects array of selects, each select is an array with the possible keys/parameters: table, cols, where, append, app, join, table_def |
||
| 2089 | * For further info about parameters see the definition of the select function, beside table, cols and where all other params are optional |
||
| 2090 | * @param int $line line-number to pass to query |
||
| 2091 | * @param string $file file-name to pass to query |
||
| 2092 | * @param string $order_by ORDER BY statement for the union |
||
| 2093 | * @param int|bool $offset offset for a limited query or False (default) |
||
| 2094 | * @param int $num_rows number of rows to return if offset set, default 0 = use default in user prefs |
||
| 2095 | * @param int $fetchmode =self::FETCH_ASSOC self::FETCH_ASSOC (default), self::FETCH_BOTH or self::FETCH_NUM |
||
| 2096 | * @return ADORecordSet or false, if the query fails |
||
| 2097 | */ |
||
| 2098 | function union($selects,$line,$file,$order_by='',$offset=false,$num_rows=0,$fetchmode=self::FETCH_ASSOC) |
||
| 2127 | |||
| 2128 | /** |
||
| 2129 | * Strip eg. a prefix from the keys of an array |
||
| 2130 | * |
||
| 2131 | * @param array $arr |
||
| 2132 | * @param string|array $strip |
||
| 2133 | * @return array |
||
| 2134 | */ |
||
| 2135 | static function strip_array_keys($arr,$strip) |
||
| 2146 | } |
||
| 2147 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.