Merged changes up to 2.3.16 into unstable
[fa-stable.git] / includes / db / connect_db.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12
13 /*
14         Converts encoding name to mysql standard.
15 */
16 function get_mysql_encoding_name($encoding)
17 {
18         $db_encoding = array(
19                 'UTF-8' => 'utf8',
20                 'ISO-8859-1' => 'latin1',
21                 'ISO-8859-2' => 'latin2',
22                 'ISO-8859-7' => 'greek',
23                 'ISO-8859-8' => 'hebrew',
24                 'ISO-8859-9' => 'latin5',
25                 'ISO-8859-13' => 'latin7',
26                 'KOI8-R' => 'koi8r',
27                 'KOI8-U' => 'koi8u',
28                 'CP850' => 'cp850',
29                 'CP866' => 'cp866',
30                 'CP932' => 'cp932',
31                 'CP1250' => 'cp1250',
32                 'CP1251' => 'cp1251',
33                 'CP1252' => 'latin1',
34                 'CP1256' => 'cp1256',
35                 'CP1257' => 'cp1257',
36                 'GB2312' => 'gb2312',
37                 'EUC-JP' => 'ujis',
38                 'EUC-KR' => 'euckr',
39                 'BIG5' => 'big5',
40                 'GBK' => 'gbk',
41                 'SHIFT_JIS' => 'sjis',
42                 'TIS-620' => 'tis620',
43                 'ASCII' => 'ascii',
44         );
45         $encoding = strtoupper($encoding);
46
47         return isset($db_encoding[$encoding]) ? $db_encoding[$encoding] : null;
48 }
49
50 /*
51         Returns 'best' collation for various locale language codes
52 */
53 function get_mysql_collation($lang=null)
54 {
55         if (!$lang)
56                 $lang = substr($_SESSION['language']->code, 0, 2);
57
58         $db_collation = array(
59                 'is' => 'icelandic',
60                 'lv' => 'latvian',
61                 'ro' => 'romanian',
62                 'sl' => 'slovenian',
63                 'pl' => 'polish',
64                 'et' => 'estonian',
65                 'es' => 'spanish', // or 'spanish2',
66                 'sw' => 'swedish',
67                 'tr' => 'turkish',
68                 'cs' => 'czech',
69                 'da' => 'danish',
70                 'lt' => 'lithuanian',
71                 'sk' => 'slovak',
72                 'sp' => 'spanish2',
73                 'fa' => 'persian',
74                 'hu' => 'hungarian',
75                 'fr' => 'roman',
76                 'it' => 'roman',
77         );
78
79         return 'utf8_'.(isset($db_collation[$lang]) ? $db_collation[$lang] : 'general').'_ci';
80 }
81 /*
82         Later we assume that database with version less than 2.4 is old database, 
83         which is subject to invalid encodings on text columns,
84         so no SET NAMES or equivalent should be used.
85 */
86 function db_fixed()
87 {
88         $result = db_query("SELECT value FROM ".TB_PREF."sys_prefs WHERE name='version_id'");
89         $data = db_fetch($result);
90         return !db_num_rows($result) // new database is fixed by default 
91                 || ($data[0] > "2.3rc");
92 }
93 /*
94         Check database default charset.
95 */
96 function db_get_charset()
97 {
98         $result = db_query("SELECT @@character_set_database");
99         $var = db_fetch($result);
100         return $var[0];
101 }
102
103 /*
104         Set mysql client encoding.
105         Default is is encoding used by default language.
106 */
107 function db_set_encoding($ui_encoding=null)
108 {
109         global $dflt_lang, $installed_languages;
110
111         if (!isset($ui_encoding))
112         {
113                 $lang = array_search_value($dflt_lang, $installed_languages, 'code');
114                 $ui_encoding = strtoupper($lang['encoding']);
115         }
116
117         if ($mysql_enc = get_mysql_encoding_name($ui_encoding))
118                 mysql_set_charset($mysql_enc);
119 }
120
121 /*
122         Connects application to company database.
123 */
124 function set_global_connection($company=-1)
125 {
126         global $db, $transaction_level, $path_to_root;
127         global  $db_connections;
128
129         include ($path_to_root . "/config_db.php");
130         if ($company == -1) 
131                 $company = $_SESSION["wa_current_user"]->company ? $_SESSION["wa_current_user"]->company : 0;
132
133         cancel_transaction(); // cancel all aborted transactions if any
134         $transaction_level = 0;
135
136         $_SESSION["wa_current_user"]->cur_con = $company;
137
138         $connection = $db_connections[$company];
139
140         $db = mysql_connect($connection["host"], $connection["dbuser"], $connection["dbpassword"]);
141                 mysql_select_db($connection["dbname"], $db);
142
143         return $db;
144 }
145
146 $db_duplicate_error_code = 1062;
147
148 function db_query($sql, $err_msg=null)
149 {
150         global $db, $show_sql, $sql_trail, $select_trail, $go_debug, $sql_queries, $Ajax,
151                 $db_connections, $db_last_inserted_id;
152         
153         // set current db prefix
154         $comp = isset($_SESSION["wa_current_user"]->cur_con) ? $_SESSION["wa_current_user"]->cur_con : 0;
155         $cur_prefix = $db_connections[$comp]['tbpref'];
156         $sql = str_replace(TB_PREF, $cur_prefix, $sql);
157
158         if ($show_sql)
159         {
160                 $Ajax->activate('footer_debug');
161                 $sql_queries .= "<pre>$sql</pre>\n<hr>";
162         }
163
164         // mysql profiling
165         global $profile_sql;
166         if (@$profile_sql) get_usec();
167                 $result = mysql_query($sql, $db);
168         if (@$profile_sql)
169         {
170                 $profile_sql= false;
171                 _vd($sql.'<br>:'.db_num_rows($result).'rows, '.get_usec());
172         }
173
174         if($sql_trail) {
175                 $db_last_inserted_id = mysql_insert_id($db);    // preserve in case trail insert is done
176                 if ($select_trail || (strstr($sql, 'SELECT') === false)) {
177                         mysql_query(
178                         "INSERT INTO ".$cur_prefix."sql_trail
179                                 (`sql`, `result`, `msg`)
180                                 VALUES(".db_escape($sql).",".($result ? 1 : 0).",
181                                 ".db_escape($err_msg).")", $db);
182                 }
183         }
184
185         if ($err_msg != null || $go_debug) {
186                 $exit = $err_msg != null;
187                 if (function_exists('xdebug_call_file'))
188                         check_db_error('<br>At file '.xdebug_call_file().':'.xdebug_call_line().':<br>'.$err_msg, $sql, $exit);
189                 else
190                         check_db_error($err_msg, $sql, $exit);
191         }
192         return $result;
193 }
194
195 function db_fetch_row ($result)
196 {
197
198         return mysql_fetch_row($result);
199 }
200
201 function db_fetch_assoc ($result)
202 {
203
204         return mysql_fetch_assoc($result);
205 }
206
207 function db_fetch ($result)
208 {
209
210         return mysql_fetch_array($result);
211 }
212
213 function db_seek (&$result,$record)
214 {
215         return mysql_data_seek($result, $record);
216 }
217
218 function db_free_result ($result)
219 {
220         if ($result)
221                 mysql_free_result($result);
222 }
223
224 function db_num_rows ($result)
225 {
226         return mysql_num_rows($result);
227 }
228
229 function db_num_fields ($result)
230 {
231         return mysql_num_fields($result);
232 }
233
234 function db_escape($value = "", $nullify = false)
235 {
236         $value = @html_entity_decode($value, ENT_QUOTES, $_SESSION['language']->encoding);
237         $value = @htmlspecialchars($value, ENT_QUOTES, $_SESSION['language']->encoding);
238
239         //reset default if second parameter is skipped
240         $nullify = ($nullify === null) ? (false) : ($nullify);
241
242         //check for null/unset/empty strings
243         if ((!isset($value)) || (is_null($value)) || ($value === "")) {
244                 $value = ($nullify) ? ("NULL") : ("''");
245         } else {
246                 if (is_string($value)) {
247                 //value is a string and should be quoted; determine best method based on available extensions
248                         if (function_exists('mysql_real_escape_string')) {
249                                 $value = "'" . mysql_real_escape_string($value) . "'";
250                         } else {
251                           $value = "'" . mysql_escape_string($value) . "'";
252                         }
253                 } else if (!is_numeric($value)) {
254                         //value is not a string nor numeric
255                         display_error("ERROR: incorrect data type send to sql query");
256                         echo '<br><br>';
257                         exit();
258                 }
259         }
260         return $value;
261 }
262
263 function db_error_no ()
264 {
265         global $db;
266         return mysql_errno($db);
267 }
268
269 function db_error_msg($conn)
270 {
271         return mysql_error($conn);
272 }
273
274 function db_insert_id()
275 {
276         global $db_last_inserted_id, $sql_trail, $db;
277
278         return $sql_trail ? $db_last_inserted_id : mysql_insert_id($db);
279 }
280
281 function db_num_affected_rows()
282 {
283         global $db;
284         return mysql_affected_rows($db);
285 }
286
287 function db_field_name($result, $n)
288 {
289         return mysql_field_name($result, $n);
290 }
291
292 function db_create_db($connection)
293 {
294         $db = mysql_connect($connection["host"] ,
295                 $connection["dbuser"], $connection["dbpassword"]);
296         if (!mysql_select_db($connection["dbname"], $db))
297         {
298                 $sql = "CREATE DATABASE IF NOT EXISTS " . $connection["dbname"] . " COLLATE ".get_mysql_collation();
299
300                 if (!mysql_query($sql) || !mysql_select_db($connection["dbname"], $db))
301                         return 0;
302         }
303         return $db;
304 }
305
306 function db_drop_db($connection)
307 {
308
309         if ($connection["tbpref"] == "")
310         {
311                 $sql = "DROP DATABASE IF EXISTS " . $connection["dbname"] . "";
312                 return mysql_query($sql);
313         }
314         else
315         {
316         $res = db_query("show table status");
317         $all_tables = array();
318         while($row = db_fetch($res))
319                 $all_tables[] = $row;
320         // get table structures
321                 foreach ($all_tables as $table)
322                 {
323                         if (strpos($table['Name'], $connection["tbpref"]) === 0)
324                                 db_query("DROP TABLE `".$table['Name'] . "`");
325                 }
326                 //deleting the tables, how??
327                 return true;
328         }
329 }
330
331 function db_close($dbase = null)
332 {
333         global $db;
334         
335         if (!$dbase)
336                 $dbase = $db;
337         return mysql_close($dbase);
338 }