.inc files migration to .inc.php (#5897)
[openemr.git] / src / Common / Database / QueryUtils.php
blobd7b64cc3af1e0e72855d628bd1c10a97c436f387
1 <?php
3 /**
4 * QueryUtils.php Is a helper class for commonly used database functions. Eventually everything in the sql.inc.php file
5 * could be migrated to this file or at least contained in this namespace.
6 * @package openemr
7 * @link http://www.open-emr.org
8 * @author Stephen Nielson <stephen@nielson.org>
9 * @copyright Copyright (c) 2021 Stephen Nielson <stephen@nielson.org>
10 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
13 namespace OpenEMR\Common\Database;
15 class QueryUtils
17 /**
18 * Function that will return an array listing
19 * of columns that exist in a table.
21 * @param string $table sql table
22 * @return array
24 public static function listTableFields($table)
26 $sql = "SHOW COLUMNS FROM " . \escape_table_name($table);
27 $field_list = array();
28 $records = self::fetchRecords($sql, [], false);
29 foreach ($records as $record) {
30 $field_list[] = $record["Field"];
33 return $field_list;
36 public static function fetchRecordsNoLog($sqlStatement, $binds)
38 // Below line is to avoid a nasty bug in windows.
39 if (empty($binds)) {
40 $binds = false;
43 $recordset = $GLOBALS['adodb']['db']->ExecuteNoLog($sqlStatement, $binds);
45 if ($recordset === false) {
46 throw new SqlQueryException($sqlStatement, "Failed to execute statement. Error: "
47 . getSqlLastError() . " Statement: " . $sqlStatement);
49 $list = [];
50 while ($record = sqlFetchArray($recordset)) {
51 $list[] = $record;
53 return $list;
55 /**
56 * Executes the SQL statement passed in and returns a list of all of the values contained in the column
57 * @param $sqlStatement
58 * @param $column string column you want returned
59 * @param array $binds
60 * @throws SqlQueryException Thrown if there is an error in the database executing the statement
61 * @return array
63 public static function fetchTableColumn($sqlStatement, $column, $binds = array())
65 $recordSet = self::sqlStatementThrowException($sqlStatement, $binds);
66 $list = [];
67 while ($record = sqlFetchArray($recordSet)) {
68 $list[] = $record[$column] ?? null;
70 return $list;
73 public static function fetchSingleValue($sqlStatement, $column, $binds = array())
75 $records = self::fetchTableColumn($sqlStatement, $column, $binds);
76 if (!empty($records[0])) {
77 return $records[0];
79 return null;
82 public static function fetchRecords($sqlStatement, $binds = array(), $noLog = false)
84 $result = self::sqlStatementThrowException($sqlStatement, $binds, $noLog);
85 $list = [];
86 while ($record = \sqlFetchArray($result)) {
87 $list[] = $record;
89 return $list;
92 /**
93 * Executes the sql statement and returns an associative array for a single column of a table
94 * @param $sqlStatement The statement to run
95 * @param $column The column you want returned
96 * @param array $binds
97 * @throws SqlQueryException Thrown if there is an error in the database executing the statement
98 * @return array
100 public static function fetchTableColumnAssoc($sqlStatement, $column, $binds = array())
102 $recordSet = self::sqlStatementThrowException($sqlStatement, $binds);
103 $list = [];
104 while ($record = sqlFetchArray($recordSet)) {
105 $list[$column] = $record[$column] ?? null;
107 return $list;
111 * Returns a row (as an array) from a sql recordset.
113 * Function that will allow use of the adodb binding
114 * feature to prevent sql-injection.
115 * It will act upon the object returned from the
116 * sqlStatement() function (and sqlQ() function).
118 * @param recordset $resultSet
119 * @return array
121 public static function fetchArrayFromResultSet($resultSet)
123 return sqlFetchArray($resultSet);
127 * Standard sql query in OpenEMR.
129 * Function that will allow use of the adodb binding
130 * feature to prevent sql-injection. Will continue to
131 * be compatible with previous function calls that do
132 * not use binding.
133 * It will return a recordset object.
134 * The sqlFetchArray() function should be used to
135 * utilize the return object.
137 * @param string $statement query
138 * @param array $binds binded variables array (optional)
139 * @param noLog boolean if true the sql statement bypasses the database logger, false logs the sql statement
140 * @throws SqlQueryException Thrown if there is an error in the database executing the statement
141 * @return recordset
143 public static function sqlStatementThrowException($statement, $binds, $noLog = false)
145 if ($noLog) {
146 return \sqlStatementNoLog($statement, $binds, true);
147 } else {
148 return \sqlStatementThrowException($statement, $binds);
153 * Sql insert query in OpenEMR.
154 * Only use this function if you need to have the
155 * id returned. If doing an insert query and do
156 * not need the id returned, then use the
157 * sqlStatement function instead.
159 * Function that will allow use of the adodb binding
160 * feature to prevent sql-injection. This function
161 * is specialized for insert function and will return
162 * the last id generated from the insert.
164 * @param string $statement query
165 * @param array $binds binded variables array (optional)
166 * @throws SqlQueryException Thrown if there is an error in the database executing the statement
167 * @return integer Last id generated from the sql insert command
169 public static function sqlInsert($statement, $binds = array())
171 // Below line is to avoid a nasty bug in windows.
172 if (empty($binds)) {
173 $binds = false;
176 //Run a adodb execute
177 // Note the auditSQLEvent function is embedded in the
178 // Execute function.
179 $recordset = $GLOBALS['adodb']['db']->Execute($statement, $binds, true);
180 if ($recordset === false) {
181 throw new SqlQueryException($statement, "Insert failed. SQL error " . getSqlLastError() . " Query: " . $statement);
184 // Return the correct last id generated using function
185 // that is safe with the audit engine.
186 return $GLOBALS['lastidado'] > 0 ? $GLOBALS['lastidado'] : $GLOBALS['adodb']['db']->Insert_ID();
190 * Shared getter for SQL selects.
192 * @param $sqlUpToFromStatement - The sql string up to (and including) the FROM line.
193 * @param $map - Query information (where clause(s), join clause(s), order, data, etc).
194 * @throws SqlQueryException If the query is invalid
195 * @return array of associative arrays | one associative array.
197 public static function selectHelper($sqlUpToFromStatement, $map)
199 $where = isset($map["where"]) ? $map["where"] : null;
200 $data = isset($map["data"]) && is_array($map['data']) ? $map["data"] : [];
201 $join = isset($map["join"]) ? $map["join"] : null;
202 $order = isset($map["order"]) ? $map["order"] : null;
203 $limit = isset($map["limit"]) ? intval($map["limit"]) : null;
205 $sql = $sqlUpToFromStatement;
207 $sql .= !empty($join) ? " " . $join : "";
208 $sql .= !empty($where) ? " " . $where : "";
209 $sql .= !empty($order) ? " " . $order : "";
210 $sql .= !empty($limit) ? " LIMIT " . $limit : "";
212 $multipleResults = sqlStatementThrowException($sql, $data);
214 $results = array();
216 while ($row = sqlFetchArray($multipleResults)) {
217 array_push($results, $row);
220 if ($limit === 1) {
221 return $results[0];
224 return $results;
227 public static function generateId()
229 return \generate_id();