3 include_once(dirname(__FILE__) . "/sqlconf.php");
4 require_once(dirname(__FILE__) . "/adodb/adodb.inc.php");
5 include_once(dirname(__FILE__) . "/log.inc");
7 if (!defined('ADODB_FETCH_ASSOC')) define('ADODB_FETCH_ASSOC', 2);
8 $database = NewADOConnection("mysql");
9 $database->PConnect($host, $login, $pass, $dbase);
11 // Modified 5/2009 by BM for UTF-8 project ---------
12 if (!$disable_utf8_flag) {
13 $success_flag = $database->Execute("SET NAMES 'utf8'");
15 error_log("PHP custom error: from openemr library/sql.inc - Unable to set up UTF8 encoding with mysql database: ".$database->ErrorMsg(), 0);
18 // -------------------------------------------------
20 $GLOBALS['adodb']['db'] = $database;
21 $GLOBALS['dbh'] = $database->_connectionID;
23 // set up associations in adodb calls (not sure why above define
24 // command does not work)
25 $GLOBALS['adodb']['db']->SetFetchMode(ADODB_FETCH_ASSOC);
27 //fmg: This makes the login screen informative when no connection can be made
28 if (!$GLOBALS['dbh']) {
29 //try to be more helpful
30 if ($host == "localhost") {
31 echo "Check that mysqld is running.<p>";
33 echo "Check that you can ping the server '$host'.<p>";
35 HelpfulDie("Could not connect to server!", mysql_error($GLOBALS['dbh']));
39 // Function that will allow use of the adodb binding
40 // feature to prevent sql-injection. Will continue to
41 // be compatible with previous function calls that do
43 // If use adodb binding, then will return a recordset object.
44 // If do not use binding, then will return a resource object.
45 // The sqlFetchArray() function should be used to
46 // utilize the return object (it will accept both recordset
47 // and resource objects).
48 function sqlStatement($statement, $binds=NULL )
50 if (is_array($binds)) {
51 // Use adodb Execute with binding and return a recordset.
52 // Note that the auditSQLEvent function is embedded
53 // in the adodb Execute command.
54 $recordset = $GLOBALS['adodb']['db']->Execute( $statement, $binds );
55 if ($recordset === FALSE) {
56 HelpfulDie("query failed: $statement", $GLOBALS['adodb']['db']->ErrorMsg());
61 // Use mysql_query and return a resource.
62 $resource = mysql_query($statement, $GLOBALS['dbh']);
63 if ($resource === FALSE) {
64 auditSQLEvent($statement, FALSE);
65 HelpfulDie("query failed: $statement", mysql_error($GLOBALS['dbh']));
67 auditSQLEvent($statement, TRUE);
72 // Function that will allow use of the adodb binding
73 // feature to prevent sql-injection.
74 // It will act upon the object returned from the
75 // sqlStatement() function (and sqlQ() function).
76 // It will automatically figure out if the input
77 // object is a recordset or a resource.
78 function sqlFetchArray($r)
80 if (!is_resource($r)) {
81 //treat as an adodb recordset
86 //ensure it's an object (ie. is set)
89 return $r->FetchRow();
92 //treat as a mysql_query resource
95 return mysql_fetch_array($r, MYSQL_ASSOC);
99 // Function that will allow use of the adodb binding
100 // feature to prevent sql-injection.
101 // This function is specialized for insert functions
102 // and will return the last id generated from the
104 function sqlInsert($statement, $binds=array())
106 //Run a adodb execute
107 // Note the auditSQLEvent function is embedded in the
108 // adodb Execute function.
109 $recordset = $GLOBALS['adodb']['db']->Execute($statement, $binds);
110 if ($recordset === FALSE) {
111 HelpfulDie("insert failed: $statement", $GLOBALS['adodb']['db']->ErrorMsg());
113 // Return the correct last id generated using function
114 // that is safe with the audit engine.
115 return getSqlLastID();
118 // Function that will allow use of the adodb binding
119 // feature to prevent sql-injection.
120 // This function is specialized for simply returning
121 // the first row of a query as an associative array.
122 // The $status_or_binds parameter can do following:
123 // FALSE or an array() - Run adodb Execute with binding,
125 // TRUE - run mysql_query for a specific case in the audit engine
126 // (library/log.inc) to skip auditing and reporting if the query
128 function sqlQuery($statement, $status_or_binds=FALSE)
130 if ((is_array($status_or_binds)) || ($status_or_binds === FALSE)) {
131 // run the adodb Execute function
132 // Note the auditSQLEvent function is embedded in the
133 // adodb Execute function.
134 if (is_array($status_or_binds)) {
135 $recordset = $GLOBALS['adodb']['db']->Execute( $statement, $status_or_binds );
138 $recordset = $GLOBALS['adodb']['db']->Execute( $statement );
140 if ($recordset === FALSE) {
141 HelpfulDie("query failed: $statement", $GLOBALS['adodb']['db']->ErrorMsg());
145 $rez = $recordset->FetchRow();
151 // run mysql_query to bypass the audit engine if error
153 $resource = mysql_query($statement, $GLOBALS['dbh']);
154 auditSQLEvent($statement, TRUE);
155 //$rez = @mysql_fetch_array($query, MYSQL_ASSOC);
156 $rez = @mysql_fetch_array($resource, MYSQL_ASSOC); //Replace $query with $resource to calculate correct checksum
163 // ViSolve: Create a seperate function for audit log calls.
164 // The audit calls are handled through separate function.
165 // Before the audit calls are executed, the mysql_insert_id() is stored in GLOBALS['lastiddao']
166 // and used in the relevant places, i.e in the mysql adodb driver files..
167 // Note: This GLOBAL variable gets its value only when the audit is enabled.
168 function sqlInsertClean_audit($statement)
170 // Get the mysql_insert_id() before the execution of the log statement
171 //$lastid=mysql_insert_id($GLOBALS['dbh']);
172 //$GLOBALS['lastidado']=$lastid;
173 // when audit is enabled and $GLOBALS['lastidado'] is not set, then set the GLOBALS irrespective of dbh and adodb handlers.
174 if ($GLOBALS['lastidado'] > 0)
177 $lastid=mysql_insert_id($GLOBALS['dbh']);
178 $GLOBALS['lastidado']=$lastid;
181 //----------run a mysql insert, return the last id generated
182 $ret = mysql_query($statement, $GLOBALS['dbh']);
183 if ($ret === FALSE) {
184 HelpfulDie("insert failed: $statement", mysql_error($GLOBALS['dbh']));
188 // Function that will safely return the last
189 // ID inserted, and accounts for
191 function getSqlLastID() {
192 if ($GLOBALS['lastidado'] >0) {
193 return $GLOBALS['lastidado'];
196 return $GLOBALS['adodb']['db']->Insert_ID();
200 // Function that will return an array listing
201 // of columns that exist in a table.
202 function sqlListFields($table) {
203 $sql = "SHOW COLUMNS FROM ". mysql_real_escape_string($table);
204 $resource = sqlQ($sql);
205 $field_list = array();
206 while($row = mysql_fetch_array($resource)) {
207 $field_list[] = $row['Field'];
212 // Function that will allow use of the adodb binding
213 // feature to prevent sql-injection.
214 // It will act upon the object returned from the
215 // sqlStatement() function (and sqlQ() function).
216 // It will automatically figure out if the input
217 // object is a recordset or a resource.
218 // It will return the number of rows.
219 function sqlNumRows($r)
221 if (!is_resource($r)) {
222 //treat as an adodb recordset
223 return $r->RecordCount();
226 //treat as a mysql_query resource
227 return mysql_num_rows($r);
231 //fmg: Much more helpful that way...
232 function HelpfulDie ($statement, $sqlerr='')
234 echo "<p><p><font color='red'>ERROR:</font> $statement<p>";
236 echo "Error: <font color='red'>$sqlerr</font><p>";
241 function generate_id () {
242 $database = $GLOBALS['adodb']['db'];
243 return $database->GenID("sequences");
246 // Does not fully incorporate the audit engine, so
247 // recommend not using this function (if bind is set,
248 // then will get logged, however if bind is not set,
249 // then will not get logged).
250 // Function that will allow use of the adodb binding
251 // feature to prevent sql-injection.
252 // Function that will allow use of the adodb binding
253 // feature to prevent sql-injection. Will continue to
254 // be compatible with previous function calls that do
256 // If use adodb binding, then will return a recordset object.
257 // If do not use binding, then will return a resource object.
258 // The sqlFetchArray() function should be used to
259 // utilize the return object (it will accept both recordset
260 // and resource objects).
261 function sqlQ($statement, $binds=NULL )
263 if (is_array($binds)) {
264 $recordset = $GLOBALS['adodb']['db']->Execute( $statement, $binds ) or
265 HelpfulDie("query failed: $statement", $GLOBALS['adodb']['db']->ErrorMsg());
269 $resource = mysql_query($statement, $GLOBALS['dbh']) or
270 HelpfulDie("query failed: $statement", mysql_error($GLOBALS['dbh']));
275 // DEPRECATED FUNCTION
277 // Function that will allow use of the adodb binding
278 // feature to prevent sql-injection.
279 // A simple wrapper for the sqlInsert() function.
280 function idSqlStatement($statement , $binds=NULL )
282 return sqlInsert($statement, $binds);
285 // DEPRECATED FUNCTION
287 // Function that will allow use of the adodb binding
288 // feature to prevent sql-injection.
289 // A simple wrapper for the sqlInsert() function.
290 function sqlInsertClean($statement, $binds=NULL )
292 return sqlInsert($statement, $binds);
295 // DEPRECATED FUNCTION
296 function sqlConnect($login,$pass,$dbase,$host,$port = '3306')
298 $GLOBALS['dbh'] = $database->_connectionID;
299 return $GLOBALS['dbh'];
302 // DEPRECATED FUNCTION
304 // Function to close the connection. PHP does
305 // this automatically, so not needed.
308 //----------Close our mysql connection
309 $closed = $GLOBALS['adodb']['db']->close or
310 HelpfulDie("could not disconnect from mysql server link", $GLOBALS['adodb']['db']->ErrorMsg());
314 // DEPRECATED FUNCTION
316 return $GLOBALS['adodb']['db'];
319 // DEPRECATED FUNCTION
320 function sqlLastID() {
321 return mysql_insert_id($GLOBALS['dbh']);