Completed
Push — CI ( ee6bd7...0f01dd )
by Adam
22:32
created
include/SugarObjects/templates/basic/language/en_us.lang.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -54,7 +54,7 @@
 block discarded – undo
54 54
 'LBL_MODIFIED_USER'=>'Modified by User',
55 55
 'LBL_LIST_NAME'=>'Name',
56 56
 'LBL_EDIT_BUTTON' => 'Edit',
57
- 'LBL_REMOVE' => 'Remove',
57
+    'LBL_REMOVE' => 'Remove',
58 58
 
59 59
 
60 60
 );
61 61
\ No newline at end of file
Please login to merge, or discard this patch.
include/SugarObjects/templates/basic/Basic.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -43,16 +43,16 @@
 block discarded – undo
43 43
     /** 
44 44
      * Constructor
45 45
      */
46
-	public function Basic()
47
-	{
48
-		parent::SugarBean();
49
-	}
46
+    public function Basic()
47
+    {
48
+        parent::SugarBean();
49
+    }
50 50
 
51
-	/**
52
-	 * @see SugarBean::get_summary_text()
53
-	 */
54
-	public function get_summary_text()
55
-	{
56
-		return "$this->name";
57
-	}
51
+    /**
52
+     * @see SugarBean::get_summary_text()
53
+     */
54
+    public function get_summary_text()
55
+    {
56
+        return "$this->name";
57
+    }
58 58
 }
59 59
\ No newline at end of file
Please login to merge, or discard this patch.
include/database/SqlsrvManager.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -143,10 +143,10 @@  discard block
 block discarded – undo
143 143
             'url'      => 'nvarchar',
144 144
             'encrypt'  => 'nvarchar',
145 145
             'file'     => 'nvarchar',
146
-	        'decimal_tpl' => 'decimal(%d, %d)',
146
+            'decimal_tpl' => 'decimal(%d, %d)',
147 147
     );
148 148
 
149
-	/**
149
+    /**
150 150
      * @see DBManager::connect()
151 151
      */
152 152
     public function connect(array $configOptions = null, $dieOnError = false)
@@ -203,10 +203,10 @@  discard block
 block discarded – undo
203 203
         return true;
204 204
     }
205 205
 
206
-	/**
206
+    /**
207 207
      * @see DBManager::query()
208
-	 */
209
-	public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
208
+     */
209
+    public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
210 210
     {
211 211
         if(is_array($sql)) {
212 212
             return $this->queryArray($sql, $dieOnError, $msg, $suppress);
@@ -232,15 +232,15 @@  discard block
 block discarded – undo
232 232
         return $result;
233 233
     }
234 234
 
235
-	/**
235
+    /**
236 236
      * @see DBManager::getFieldsArray()
237 237
      */
238
-	public function getFieldsArray($result, $make_lower_case = false)
239
-	{
238
+    public function getFieldsArray($result, $make_lower_case = false)
239
+    {
240 240
         $field_array = array();
241 241
 
242 242
         if ( !$result ) {
243
-        	return false;
243
+            return false;
244 244
         }
245 245
 
246 246
         foreach ( sqlsrv_field_metadata($result) as $fieldMetadata ) {
@@ -252,16 +252,16 @@  discard block
 block discarded – undo
252 252
         }
253 253
 
254 254
         return $field_array;
255
-	}
255
+    }
256 256
 
257
-	/**
258
-	 * @see DBManager::fetchRow()
259
-	 */
260
-	public function fetchRow($result)
261
-	{
262
-		if (empty($result))	return false;
257
+    /**
258
+     * @see DBManager::fetchRow()
259
+     */
260
+    public function fetchRow($result)
261
+    {
262
+        if (empty($result))	return false;
263 263
 
264
-	    $row = sqlsrv_fetch_array($result,SQLSRV_FETCH_ASSOC);
264
+        $row = sqlsrv_fetch_array($result,SQLSRV_FETCH_ASSOC);
265 265
         if (empty($row)) {
266 266
             return false;
267 267
         }
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
         }
278 278
 
279 279
         return $row;
280
-	}
280
+    }
281 281
 
282 282
     /**
283 283
      * @see DBManager::convert()
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
             return parent::convert($string, $type, $additional_parameters);
292 292
     }
293 293
 
294
-	/**
294
+    /**
295 295
      * Compares two vardefs. Overriding 39098  due to bug: 39098 . IN 6.0 we changed the id columns to dbType = 'id'
296 296
      * for example emails_beans.  In 554 the field email_id was nvarchar but in 6.0 since it id dbType = 'id' we would want to alter
297 297
      * it to varchar. This code will prevent it.
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
      */
318 318
     public function disconnect()
319 319
     {
320
-    	$GLOBALS['log']->debug('Calling Mssql::disconnect()');
320
+        $GLOBALS['log']->debug('Calling Mssql::disconnect()');
321 321
         if(!empty($this->database)){
322 322
             $this->freeResult();
323 323
             sqlsrv_close($this->database);
@@ -335,10 +335,10 @@  discard block
 block discarded – undo
335 335
     }
336 336
 
337 337
 
338
-	/**
339
-	 * Detect if no clustered index has been created for a table; if none created then just pick the first index and make it that
340
-	 *
341
-	 * @see MssqlHelper::indexSQL()
338
+    /**
339
+     * Detect if no clustered index has been created for a table; if none created then just pick the first index and make it that
340
+     *
341
+     * @see MssqlHelper::indexSQL()
342 342
      */
343 343
     public function getConstraintSql($indices, $table)
344 344
     {
@@ -378,12 +378,12 @@  discard block
 block discarded – undo
378 378
                 $columns[$column_name]['len']=strtolower($row['PRECISION']);
379 379
                 $columns[$column_name]['len'].=','.strtolower($row['SCALE']);
380 380
             }
381
-			elseif ( in_array($row['TYPE_NAME'],array('nchar','nvarchar')) ) {
382
-				$columns[$column_name]['len']=strtolower($row['PRECISION']);
383
-				if ( $row['TYPE_NAME'] == 'nvarchar' && $row['PRECISION'] == '0' ) {
384
-				    $columns[$column_name]['len']='max';
385
-				}
386
-			}
381
+            elseif ( in_array($row['TYPE_NAME'],array('nchar','nvarchar')) ) {
382
+                $columns[$column_name]['len']=strtolower($row['PRECISION']);
383
+                if ( $row['TYPE_NAME'] == 'nvarchar' && $row['PRECISION'] == '0' ) {
384
+                    $columns[$column_name]['len']='max';
385
+                }
386
+            }
387 387
             elseif ( !in_array($row['TYPE_NAME'],array('datetime','text')) ) {
388 388
                 $columns[$column_name]['len']=strtolower($row['LENGTH']);
389 389
             }
@@ -488,21 +488,21 @@  discard block
 block discarded – undo
488 488
         return "TRUNCATE TABLE $name";
489 489
     }
490 490
 
491
-	/**
492
-	 * (non-PHPdoc)
493
-	 * @see DBManager::lastDbError()
494
-	 */
491
+    /**
492
+     * (non-PHPdoc)
493
+     * @see DBManager::lastDbError()
494
+     */
495 495
     public function lastDbError()
496 496
     {
497 497
         $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS);
498 498
         if(empty($errors)) return false;
499 499
         global $app_strings;
500 500
         if (empty($app_strings)
501
-		    or !isset($app_strings['ERR_MSSQL_DB_CONTEXT'])
502
-			or !isset($app_strings['ERR_MSSQL_WARNING']) ) {
501
+            or !isset($app_strings['ERR_MSSQL_DB_CONTEXT'])
502
+            or !isset($app_strings['ERR_MSSQL_WARNING']) ) {
503 503
         //ignore the message from sql-server if $app_strings array is empty. This will happen
504 504
         //only if connection if made before languge is set.
505
-		    return false;
505
+            return false;
506 506
         }
507 507
         $messages = array();
508 508
         foreach($errors as $error) {
@@ -515,7 +515,7 @@  discard block
 block discarded – undo
515 515
             }
516 516
             $sqlpos = strpos($sqlmsg, $app_strings['ERR_MSSQL_DB_CONTEXT']);
517 517
             $sqlpos2 = strpos($sqlmsg, $app_strings['ERR_MSSQL_WARNING']);
518
-    		if ( $sqlpos !== false || $sqlpos2 !== false) {
518
+            if ( $sqlpos !== false || $sqlpos2 !== false) {
519 519
                     continue;
520 520
             }
521 521
             $messages[] = $sqlmsg;
Please login to merge, or discard this patch.
include/database/MssqlManager.php 1 patch
Indentation   +156 added lines, -156 removed lines patch added patch discarded remove patch
@@ -140,8 +140,8 @@  discard block
 block discarded – undo
140 140
             'relate'   => 'varchar',
141 141
             'multienum'=> 'text',
142 142
             'html'     => 'text',
143
-			'longhtml' => 'text',
144
-    		'datetime' => 'datetime',
143
+            'longhtml' => 'text',
144
+            'datetime' => 'datetime',
145 145
             'datetimecombo' => 'datetime',
146 146
             'time'     => 'datetime',
147 147
             'bool'     => 'bit',
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
             'url'      => 'varchar',
157 157
             'encrypt'  => 'varchar',
158 158
             'file'     => 'varchar',
159
-	        'decimal_tpl' => 'decimal(%d, %d)',
159
+            'decimal_tpl' => 'decimal(%d, %d)',
160 160
             );
161 161
 
162 162
     protected $connectOptions = null;
@@ -236,16 +236,16 @@  discard block
 block discarded – undo
236 236
         //it will throw an Unable to select database message.
237 237
 
238 238
         if(!empty($configOptions['db_name']) && !@mssql_select_db($configOptions['db_name'], $this->database)){
239
-			$connected = false;
240
-			for($i=0;$i<5;$i++){
241
-				usleep(200000);
242
-				if(@mssql_select_db($configOptions['db_name'], $this->database)){
243
-					$connected = true;
244
-					break;
245
-				}
246
-			}
247
-			if(!$connected){
248
-			    $GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}");
239
+            $connected = false;
240
+            for($i=0;$i<5;$i++){
241
+                usleep(200000);
242
+                if(@mssql_select_db($configOptions['db_name'], $this->database)){
243
+                    $connected = true;
244
+                    break;
245
+                }
246
+            }
247
+            if(!$connected){
248
+                $GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}");
249 249
                 if($dieOnError) {
250 250
                     if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
251 251
                         sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
@@ -255,8 +255,8 @@  discard block
 block discarded – undo
255 255
                 } else {
256 256
                     return false;
257 257
                 }
258
-			}
259
-         }
258
+            }
259
+            }
260 260
 
261 261
         if(!$this->checkError('Could Not Connect', $dieOnError))
262 262
             $GLOBALS['log']->info("connected to db");
@@ -267,18 +267,18 @@  discard block
 block discarded – undo
267 267
         return true;
268 268
     }
269 269
 
270
-	/**
270
+    /**
271 271
      * @see DBManager::version()
272 272
      */
273 273
     public function version()
274 274
     {
275 275
         return $this->getOne("SELECT @@VERSION as version");
276
-	}
276
+    }
277 277
 
278
-	/**
278
+    /**
279 279
      * @see DBManager::query()
280
-	 */
281
-	public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
280
+     */
281
+    public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
282 282
     {
283 283
         if(is_array($sql)) {
284 284
             return $this->queryArray($sql, $dieOnError, $msg, $suppress);
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
         if ((substr_count($sql, "'") & 1))
288 288
             $GLOBALS['log']->error("SQL statement[" . $sql . "] has odd number of single quotes.");
289 289
 
290
-		$sql = $this->_appendN($sql);
290
+        $sql = $this->_appendN($sql);
291 291
 
292 292
         $GLOBALS['log']->info('Query:' . $sql);
293 293
         $this->checkConnection();
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
         $this->query_time = microtime(true);
296 296
 
297 297
         // Bug 34892 - Clear out previous error message by checking the @@ERROR global variable
298
-		@mssql_query("SELECT @@ERROR", $this->database);
298
+        @mssql_query("SELECT @@ERROR", $this->database);
299 299
 
300 300
         $result = $suppress?@mssql_query($sql, $this->database):mssql_query($sql, $this->database);
301 301
 
@@ -305,18 +305,18 @@  discard block
 block discarded – undo
305 305
             //				  not affect the functionality of the query
306 306
             $sqlmsg = mssql_get_last_message();
307 307
             $sqlpos = strpos($sqlmsg, 'Changed database context to');
308
-			$sqlpos2 = strpos($sqlmsg, 'Warning:');
309
-			$sqlpos3 = strpos($sqlmsg, 'Checking identity information:');
308
+            $sqlpos2 = strpos($sqlmsg, 'Warning:');
309
+            $sqlpos3 = strpos($sqlmsg, 'Checking identity information:');
310 310
 
311
-			if ($sqlpos !== false || $sqlpos2 !== false || $sqlpos3 !== false)		// if sqlmsg has 'Changed database context to', just log it
312
-				$GLOBALS['log']->debug($sqlmsg . ": " . $sql );
313
-			else {
314
-				$GLOBALS['log']->fatal($sqlmsg . ": " . $sql );
315
-				if($dieOnError)
316
-					sugar_die('SQL Error : ' . $sqlmsg);
317
-				else
318
-					echo 'SQL Error : ' . $sqlmsg;
319
-			}
311
+            if ($sqlpos !== false || $sqlpos2 !== false || $sqlpos3 !== false)		// if sqlmsg has 'Changed database context to', just log it
312
+                $GLOBALS['log']->debug($sqlmsg . ": " . $sql );
313
+            else {
314
+                $GLOBALS['log']->fatal($sqlmsg . ": " . $sql );
315
+                if($dieOnError)
316
+                    sugar_die('SQL Error : ' . $sqlmsg);
317
+                else
318
+                    echo 'SQL Error : ' . $sqlmsg;
319
+            }
320 320
         }
321 321
 
322 322
         $this->query_time = microtime(true) - $this->query_time;
@@ -426,8 +426,8 @@  discard block
 block discarded – undo
426 426
         return $limitUnionSQL;
427 427
     }
428 428
 
429
-	/**
430
-	 * FIXME: verify and thoroughly test this code, these regexps look fishy
429
+    /**
430
+     * FIXME: verify and thoroughly test this code, these regexps look fishy
431 431
      * @see DBManager::limitQuery()
432 432
      */
433 433
     public function limitQuery($sql, $start, $count, $dieOnError = false, $msg = '', $execute = true)
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
                     }else{
570 570
                         //if there is a distinct clause, form query with rownumber after distinct
571 571
                         if ($hasDistinct) {
572
-                             $newSQL = "SELECT TOP $count * FROM
572
+                                $newSQL = "SELECT TOP $count * FROM
573 573
                                             (
574 574
                             SELECT ROW_NUMBER() OVER (ORDER BY ".$grpByStr.") AS row_number, count(*) counter, " . $distinctSQLARRAY[0] . "
575 575
                                                         " . $distinctSQLARRAY[1] . "
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
                                             WHERE row_number > $start";
580 580
                         }
581 581
                         else {
582
-                             $newSQL = "SELECT TOP $count * FROM
582
+                                $newSQL = "SELECT TOP $count * FROM
583 583
                                            (
584 584
                                   " . $matches[1] . " ROW_NUMBER() OVER (ORDER BY " . $sqlArray['FROM'][0]['alias'] . ".id) AS row_number, " . $matches[2] . $matches[3]. "
585 585
                                            )
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
         while ($i<$count && $offset<strlen($p_sql)) {
627 627
             if ($offset > strlen($p_sql))
628 628
             {
629
-				break;
629
+                break;
630 630
             }
631 631
 
632 632
             $beg_sin = strpos($p_sql, $strip_beg, $offset);
@@ -665,7 +665,7 @@  discard block
 block discarded – undo
665 665
      * @param  array  $pattern_array
666 666
      * @return string
667 667
      */
668
-	private function addPatternToSQL($token, array $pattern_array)
668
+    private function addPatternToSQL($token, array $pattern_array)
669 669
     {
670 670
         //strip all single quotes out
671 671
         $pattern_array = array_reverse($pattern_array);
@@ -684,7 +684,7 @@  discard block
 block discarded – undo
684 684
      * @param  string $alias
685 685
      * @return string
686 686
      */
687
-	private function getAliasFromSQL($sql, $alias)
687
+    private function getAliasFromSQL($sql, $alias)
688 688
     {
689 689
         $matches = array();
690 690
         preg_match('/^(.*SELECT)(.*?FROM.*WHERE)(.*)$/isU',$sql, $matches);
@@ -786,7 +786,7 @@  discard block
 block discarded – undo
786 786
 
787 787
         // If there is no ordering direction (ASC/DESC), use ASC by default
788 788
         if (strpos($orig_order_match, " ") === false) {
789
-        	$orig_order_match .= " ASC";
789
+            $orig_order_match .= " ASC";
790 790
         }
791 791
 
792 792
         //grab first space in order by
@@ -810,11 +810,11 @@  discard block
 block discarded – undo
810 810
                 $lastSpacePos = strrpos($containsColStr, " ");
811 811
                 //use positions of column name, space before name, and length of column to find the correct column name
812 812
                 $col_name = substr($sql, $lastSpacePos, $colMatchPos-$lastSpacePos+strlen($orderMatch));
813
-				//bug 25485. When sorting by a custom field in Account List and then pressing NEXT >, system gives an error
814
-				$containsCommaPos = strpos($col_name, ",");
815
-				if($containsCommaPos !== false) {
816
-					$col_name = substr($col_name, $containsCommaPos+1);
817
-				}
813
+                //bug 25485. When sorting by a custom field in Account List and then pressing NEXT >, system gives an error
814
+                $containsCommaPos = strpos($col_name, ",");
815
+                if($containsCommaPos !== false) {
816
+                    $col_name = substr($col_name, $containsCommaPos+1);
817
+                }
818 818
                 //add the "asc/desc" order back
819 819
                 $col_name = $col_name. " ". $asc_desc;
820 820
 
@@ -967,14 +967,14 @@  discard block
 block discarded – undo
967 967
     }
968 968
 
969 969
 
970
-	/**
970
+    /**
971 971
      * @see DBManager::getFieldsArray()
972 972
      */
973
-	public function getFieldsArray($result, $make_lower_case = false)
974
-	{
975
-		$field_array = array();
973
+    public function getFieldsArray($result, $make_lower_case = false)
974
+    {
975
+        $field_array = array();
976 976
 
977
-		if(! isset($result) || empty($result))
977
+        if(! isset($result) || empty($result))
978 978
             return 0;
979 979
 
980 980
         $i = 0;
@@ -991,37 +991,37 @@  discard block
 block discarded – undo
991 991
         }
992 992
 
993 993
         return $field_array;
994
-	}
994
+    }
995 995
 
996 996
     /**
997 997
      * @see DBManager::getAffectedRowCount()
998 998
      */
999
-	public function getAffectedRowCount($result)
999
+    public function getAffectedRowCount($result)
1000 1000
     {
1001 1001
         return $this->getOne("SELECT @@ROWCOUNT");
1002 1002
     }
1003 1003
 
1004
-	/**
1005
-	 * @see DBManager::fetchRow()
1006
-	 */
1007
-	public function fetchRow($result)
1008
-	{
1009
-		if (empty($result))	return false;
1004
+    /**
1005
+     * @see DBManager::fetchRow()
1006
+     */
1007
+    public function fetchRow($result)
1008
+    {
1009
+        if (empty($result))	return false;
1010 1010
 
1011 1011
         $row = mssql_fetch_assoc($result);
1012 1012
         //MSSQL returns a space " " when a varchar column is empty ("") and not null.
1013 1013
         //We need to iterate through the returned row array and strip empty spaces
1014 1014
         if(!empty($row)){
1015 1015
             foreach($row as $key => $column) {
1016
-               //notice we only strip if one space is returned.  we do not want to strip
1017
-               //strings with intentional spaces (" foo ")
1018
-               if (!empty($column) && $column ==" ") {
1019
-                   $row[$key] = '';
1020
-               }
1016
+                //notice we only strip if one space is returned.  we do not want to strip
1017
+                //strings with intentional spaces (" foo ")
1018
+                if (!empty($column) && $column ==" ") {
1019
+                    $row[$key] = '';
1020
+                }
1021 1021
             }
1022 1022
         }
1023 1023
         return $row;
1024
-	}
1024
+    }
1025 1025
 
1026 1026
     /**
1027 1027
      * @see DBManager::quote()
@@ -1069,7 +1069,7 @@  discard block
 block discarded – undo
1069 1069
             if (!empty($r)) {
1070 1070
                 while ($a = $this->fetchByAssoc($r)) {
1071 1071
                     $row = array_values($a);
1072
-					$tables[]=$row[0];
1072
+                    $tables[]=$row[0];
1073 1073
                 }
1074 1074
                 return $tables;
1075 1075
             }
@@ -1126,7 +1126,7 @@  discard block
 block discarded – undo
1126 1126
                 )
1127 1127
                 ";
1128 1128
                 //create full text index
1129
-                 $FTSqry[] = "CREATE FULLTEXT INDEX ON fts_wakeup
1129
+                    $FTSqry[] = "CREATE FULLTEXT INDEX ON fts_wakeup
1130 1130
                 (
1131 1131
                     body
1132 1132
                     Language 0X0
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
                     $len = $this->date_formats[$additional_parameters[0]];
1196 1196
                     return "LEFT(CONVERT(varchar($len),". $string . ",120),$len)";
1197 1197
                 } else {
1198
-                   return "LEFT(CONVERT(varchar(10),". $string . ",120),10)";
1198
+                    return "LEFT(CONVERT(varchar(10),". $string . ",120),10)";
1199 1199
                 }
1200 1200
             case 'ifnull':
1201 1201
                 if(empty($additional_parameters_string)) {
@@ -1237,14 +1237,14 @@  discard block
 block discarded – undo
1237 1237
             case 'datetime': return substr($string, 0,19);
1238 1238
             case 'date': return substr($string, 0, 10);
1239 1239
             case 'time': return substr($string, 11);
1240
-		}
1241
-		return $string;
1240
+        }
1241
+        return $string;
1242 1242
     }
1243 1243
 
1244 1244
     /**
1245 1245
      * @see DBManager::createTableSQLParams()
1246 1246
      */
1247
-	public function createTableSQLParams($tablename, $fieldDefs, $indices)
1247
+    public function createTableSQLParams($tablename, $fieldDefs, $indices)
1248 1248
     {
1249 1249
         if (empty($tablename) || empty($fieldDefs))
1250 1250
             return '';
@@ -1322,7 +1322,7 @@  discard block
 block discarded – undo
1322 1322
             break;
1323 1323
         default:
1324 1324
             return '';
1325
-    	}
1325
+        }
1326 1326
     }
1327 1327
 
1328 1328
     /**
@@ -1338,14 +1338,14 @@  discard block
 block discarded – undo
1338 1338
         $columns = array();
1339 1339
         if ($this->isFieldArray($fieldDefs)) {
1340 1340
             foreach ($fieldDefs as $def)
1341
-      		{
1342
-          		//if the column is being modified drop the default value
1343
-          		//constraint if it exists. alterSQLRep will add the constraint back
1344
-          		if (!empty($constraints[$def['name']])) {
1345
-          			$sql.=" ALTER TABLE " . $tablename . " DROP CONSTRAINT " . $constraints[$def['name']];
1346
-          		}
1347
-          		//check to see if we need to drop related indexes before the alter
1348
-          		$indices = $this->get_indices($tablename);
1341
+                {
1342
+                    //if the column is being modified drop the default value
1343
+                    //constraint if it exists. alterSQLRep will add the constraint back
1344
+                    if (!empty($constraints[$def['name']])) {
1345
+                        $sql.=" ALTER TABLE " . $tablename . " DROP CONSTRAINT " . $constraints[$def['name']];
1346
+                    }
1347
+                    //check to see if we need to drop related indexes before the alter
1348
+                    $indices = $this->get_indices($tablename);
1349 1349
                 foreach ( $indices as $index ) {
1350 1350
                     if ( in_array($def['name'],$index['fields']) ) {
1351 1351
                         $sql  .= ' ' . $this->add_drop_constraint($tablename,$index,true).' ';
@@ -1353,16 +1353,16 @@  discard block
 block discarded – undo
1353 1353
                     }
1354 1354
                 }
1355 1355
 
1356
-          		$columns[] = $this->alterSQLRep($action, $def, $ignoreRequired,$tablename);
1357
-      		}
1356
+                    $columns[] = $this->alterSQLRep($action, $def, $ignoreRequired,$tablename);
1357
+                }
1358 1358
         }
1359 1359
         else {
1360 1360
             //if the column is being modified drop the default value
1361
-      		//constraint if it exists. alterSQLRep will add the constraint back
1362
-      		if (!empty($constraints[$fieldDefs['name']])) {
1363
-      			$sql.=" ALTER TABLE " . $tablename . " DROP CONSTRAINT " . $constraints[$fieldDefs['name']];
1364
-      		}
1365
-      		//check to see if we need to drop related indexes before the alter
1361
+                //constraint if it exists. alterSQLRep will add the constraint back
1362
+                if (!empty($constraints[$fieldDefs['name']])) {
1363
+                    $sql.=" ALTER TABLE " . $tablename . " DROP CONSTRAINT " . $constraints[$fieldDefs['name']];
1364
+                }
1365
+                //check to see if we need to drop related indexes before the alter
1366 1366
             $indices = $this->get_indices($tablename);
1367 1367
             foreach ( $indices as $index ) {
1368 1368
                 if ( in_array($fieldDefs['name'],$index['fields']) ) {
@@ -1372,7 +1372,7 @@  discard block
 block discarded – undo
1372 1372
             }
1373 1373
 
1374 1374
 
1375
-          	$columns[] = $this->alterSQLRep($action, $fieldDefs, $ignoreRequired,$tablename);
1375
+                $columns[] = $this->alterSQLRep($action, $fieldDefs, $ignoreRequired,$tablename);
1376 1376
         }
1377 1377
 
1378 1378
         $columns = implode(", ", $columns);
@@ -1383,8 +1383,8 @@  discard block
 block discarded – undo
1383 1383
 
1384 1384
     protected function setAutoIncrement($table, $field_name)
1385 1385
     {
1386
-		return "identity(1,1)";
1387
-	}
1386
+        return "identity(1,1)";
1387
+    }
1388 1388
 
1389 1389
     /**
1390 1390
      * @see DBManager::setAutoIncrementStart()
@@ -1393,16 +1393,16 @@  discard block
 block discarded – undo
1393 1393
     {
1394 1394
         if($start_value > 1)
1395 1395
             $start_value -= 1;
1396
-		$this->query("DBCC CHECKIDENT ('$table', RESEED, $start_value) WITH NO_INFOMSGS");
1396
+        $this->query("DBCC CHECKIDENT ('$table', RESEED, $start_value) WITH NO_INFOMSGS");
1397 1397
         return true;
1398 1398
     }
1399 1399
 
1400
-	/**
1400
+    /**
1401 1401
      * @see DBManager::getAutoIncrement()
1402 1402
      */
1403 1403
     public function getAutoIncrement($table, $field_name)
1404 1404
     {
1405
-		$result = $this->getOne("select IDENT_CURRENT('$table') + IDENT_INCR ( '$table' ) as 'Auto_increment'");
1405
+        $result = $this->getOne("select IDENT_CURRENT('$table') + IDENT_INCR ( '$table' ) as 'Auto_increment'");
1406 1406
         return $result;
1407 1407
     }
1408 1408
 
@@ -1457,8 +1457,8 @@  discard block
 block discarded – undo
1457 1457
                 $columns[$column_name]['len']=strtolower($row['PRECISION']);
1458 1458
                 $columns[$column_name]['len'].=','.strtolower($row['SCALE']);
1459 1459
             }
1460
-			elseif ( in_array($row['TYPE_NAME'],array('nchar','nvarchar')) )
1461
-				$columns[$column_name]['len']=strtolower($row['PRECISION']);
1460
+            elseif ( in_array($row['TYPE_NAME'],array('nchar','nvarchar')) )
1461
+                $columns[$column_name]['len']=strtolower($row['PRECISION']);
1462 1462
             elseif ( !in_array($row['TYPE_NAME'],array('datetime','text')) )
1463 1463
                 $columns[$column_name]['len']=strtolower($row['LENGTH']);
1464 1464
             if ( stristr($row['TYPE_NAME'],'identity') ) {
@@ -1585,7 +1585,7 @@  discard block
 block discarded – undo
1585 1585
     protected function full_text_indexing_enabled($dbname = null)
1586 1586
     {
1587 1587
         // check to see if we already have install setting in session
1588
-    	if(!isset($_SESSION['IsFulltextInstalled']))
1588
+        if(!isset($_SESSION['IsFulltextInstalled']))
1589 1589
             $_SESSION['IsFulltextInstalled'] = $this->full_text_indexing_installed();
1590 1590
 
1591 1591
         // check to see if FTS Indexing service is installed
@@ -1593,27 +1593,27 @@  discard block
 block discarded – undo
1593 1593
             return false;
1594 1594
 
1595 1595
         // grab the dbname if it was not passed through
1596
-		if (empty($dbname)) {
1597
-			global $sugar_config;
1598
-			$dbname = $sugar_config['dbconfig']['db_name'];
1599
-		}
1596
+        if (empty($dbname)) {
1597
+            global $sugar_config;
1598
+            $dbname = $sugar_config['dbconfig']['db_name'];
1599
+        }
1600 1600
         //we already know that Indexing service is installed, now check
1601 1601
         //to see if it is enabled
1602
-		$res = $this->getOne("SELECT DATABASEPROPERTY('$dbname', 'IsFulltextEnabled') ftext");
1602
+        $res = $this->getOne("SELECT DATABASEPROPERTY('$dbname', 'IsFulltextEnabled') ftext");
1603 1603
         return !empty($res);
1604
-	}
1604
+    }
1605 1605
 
1606 1606
     /**
1607 1607
      * Creates default full text catalog
1608 1608
      */
1609
-	protected function create_default_full_text_catalog()
1609
+    protected function create_default_full_text_catalog()
1610 1610
     {
1611
-		if ($this->full_text_indexing_enabled()) {
1612
-		    $catalog = $this->ftsCatalogName();
1611
+        if ($this->full_text_indexing_enabled()) {
1612
+            $catalog = $this->ftsCatalogName();
1613 1613
             $GLOBALS['log']->debug("Creating the default catalog for full-text indexing, $catalog");
1614 1614
 
1615 1615
             //drop catalog if exists.
1616
-			$ret = $this->query("
1616
+            $ret = $this->query("
1617 1617
                 if not exists(
1618 1618
                     select *
1619 1619
                         from sys.fulltext_catalogs
@@ -1621,11 +1621,11 @@  discard block
 block discarded – undo
1621 1621
                         )
1622 1622
                 CREATE FULLTEXT CATALOG $catalog");
1623 1623
 
1624
-			if (empty($ret)) {
1625
-				$GLOBALS['log']->error("Error creating default full-text catalog, $catalog");
1626
-			}
1627
-		}
1628
-	}
1624
+            if (empty($ret)) {
1625
+                $GLOBALS['log']->error("Error creating default full-text catalog, $catalog");
1626
+            }
1627
+        }
1628
+    }
1629 1629
 
1630 1630
     /**
1631 1631
      * Function returns name of the constraint automatically generated by sql-server.
@@ -1635,7 +1635,7 @@  discard block
 block discarded – undo
1635 1635
      * @param  string $column
1636 1636
      * @return string
1637 1637
      */
1638
-	private function get_field_default_constraint_name($table, $column = null)
1638
+    private function get_field_default_constraint_name($table, $column = null)
1639 1639
     {
1640 1640
         static $results = array();
1641 1641
 
@@ -1670,7 +1670,7 @@  discard block
 block discarded – undo
1670 1670
         }
1671 1671
 
1672 1672
         return null;
1673
-	}
1673
+    }
1674 1674
 
1675 1675
     /**
1676 1676
      * @see DBManager::massageFieldDef()
@@ -1692,7 +1692,7 @@  discard block
 block discarded – undo
1692 1692
                 case 'varchar'  :
1693 1693
                 case 'nvarchar' :
1694 1694
                                   $fieldDef['len'] = $this->isTextType($fieldDef['dbType']) ? 'max' : '255';
1695
-                                  break;
1695
+                                    break;
1696 1696
                 case 'image'    : $fieldDef['len'] = '2147483647'; break;
1697 1697
                 case 'ntext'    : $fieldDef['len'] = '2147483646'; break;   // Note: this is from legacy code, don't know if this is correct
1698 1698
             }
@@ -1701,7 +1701,7 @@  discard block
 block discarded – undo
1701 1701
            && empty($fieldDef['precision'])
1702 1702
            && !strpos($fieldDef['len'], ','))
1703 1703
         {
1704
-             $fieldDef['len'] .= ',0'; // Adding 0 precision if it is not specified
1704
+                $fieldDef['len'] .= ',0'; // Adding 0 precision if it is not specified
1705 1705
         }
1706 1706
 
1707 1707
         if(empty($fieldDef['default'])
@@ -1709,8 +1709,8 @@  discard block
 block discarded – undo
1709 1709
         {
1710 1710
             $fieldDef['default'] = '0';
1711 1711
         }
1712
-		if (isset($fieldDef['required']) && $fieldDef['required'] && !isset($fieldDef['default']) )
1713
-			$fieldDef['default'] = '';
1712
+        if (isset($fieldDef['required']) && $fieldDef['required'] && !isset($fieldDef['default']) )
1713
+            $fieldDef['default'] = '';
1714 1714
 //        if ($fieldDef['type'] == 'bit' && empty($fieldDef['len']) )
1715 1715
 //            $fieldDef['len'] = '1';
1716 1716
 //		if ($fieldDef['type'] == 'bool' && empty($fieldDef['len']) )
@@ -1739,30 +1739,30 @@  discard block
 block discarded – undo
1739 1739
      */
1740 1740
     protected function oneColumnSQLRep($fieldDef, $ignoreRequired = false, $table = '', $return_as_array = false)
1741 1741
     {
1742
-    	//Bug 25814
1743
-		if(isset($fieldDef['name'])){
1744
-		    $colType = $this->getFieldType($fieldDef);
1745
-        	if(stristr($this->getFieldType($fieldDef), 'decimal') && isset($fieldDef['len'])){
1746
-				$fieldDef['len'] = min($fieldDef['len'],38);
1747
-			}
1748
-		    //bug: 39690 float(8) is interpreted as real and this generates a diff when doing repair
1749
-			if(stristr($colType, 'float') && isset($fieldDef['len']) && $fieldDef['len'] == 8){
1750
-				unset($fieldDef['len']);
1751
-			}
1752
-		}
1753
-
1754
-		// always return as array for post-processing
1755
-		$ref = parent::oneColumnSQLRep($fieldDef, $ignoreRequired, $table, true);
1756
-
1757
-		// Bug 24307 - Don't add precision for float fields.
1758
-		if ( stristr($ref['colType'],'float') )
1759
-			$ref['colType'] = preg_replace('/(,\d+)/','',$ref['colType']);
1742
+        //Bug 25814
1743
+        if(isset($fieldDef['name'])){
1744
+            $colType = $this->getFieldType($fieldDef);
1745
+            if(stristr($this->getFieldType($fieldDef), 'decimal') && isset($fieldDef['len'])){
1746
+                $fieldDef['len'] = min($fieldDef['len'],38);
1747
+            }
1748
+            //bug: 39690 float(8) is interpreted as real and this generates a diff when doing repair
1749
+            if(stristr($colType, 'float') && isset($fieldDef['len']) && $fieldDef['len'] == 8){
1750
+                unset($fieldDef['len']);
1751
+            }
1752
+        }
1753
+
1754
+        // always return as array for post-processing
1755
+        $ref = parent::oneColumnSQLRep($fieldDef, $ignoreRequired, $table, true);
1756
+
1757
+        // Bug 24307 - Don't add precision for float fields.
1758
+        if ( stristr($ref['colType'],'float') )
1759
+            $ref['colType'] = preg_replace('/(,\d+)/','',$ref['colType']);
1760 1760
 
1761 1761
         if ( $return_as_array )
1762 1762
             return $ref;
1763 1763
         else
1764 1764
             return "{$ref['name']} {$ref['colType']} {$ref['default']} {$ref['required']} {$ref['auto_increment']}";
1765
-	}
1765
+    }
1766 1766
 
1767 1767
     /**
1768 1768
      * Saves changes to module's audit table
@@ -1771,13 +1771,13 @@  discard block
 block discarded – undo
1771 1771
      * @param array  $changes changes
1772 1772
      */
1773 1773
     public function save_audit_records(SugarBean $bean, $changes)
1774
-	{
1775
-		//Bug 25078 fixed by Martin Hu: sqlserver haven't 'date' type, trim extra "00:00:00"
1776
-		if($changes['data_type'] == 'date'){
1777
-			$changes['before'] = str_replace(' 00:00:00','',$changes['before']);
1778
-		}
1779
-		parent::save_audit_records($bean,$changes);
1780
-	}
1774
+    {
1775
+        //Bug 25078 fixed by Martin Hu: sqlserver haven't 'date' type, trim extra "00:00:00"
1776
+        if($changes['data_type'] == 'date'){
1777
+            $changes['before'] = str_replace(' 00:00:00','',$changes['before']);
1778
+        }
1779
+        parent::save_audit_records($bean,$changes);
1780
+    }
1781 1781
 
1782 1782
     /**
1783 1783
      * Disconnects from the database
@@ -1786,7 +1786,7 @@  discard block
 block discarded – undo
1786 1786
      */
1787 1787
     public function disconnect()
1788 1788
     {
1789
-    	$GLOBALS['log']->debug('Calling Mssql::disconnect()');
1789
+        $GLOBALS['log']->debug('Calling Mssql::disconnect()');
1790 1790
         if(!empty($this->database)){
1791 1791
             $this->freeResult();
1792 1792
             mssql_close($this->database);
@@ -1803,21 +1803,21 @@  discard block
 block discarded – undo
1803 1803
             mssql_free_result($dbResult);
1804 1804
     }
1805 1805
 
1806
-	/**
1807
-	 * (non-PHPdoc)
1808
-	 * @see DBManager::lastDbError()
1809
-	 */
1806
+    /**
1807
+     * (non-PHPdoc)
1808
+     * @see DBManager::lastDbError()
1809
+     */
1810 1810
     public function lastDbError()
1811 1811
     {
1812 1812
         $sqlmsg = mssql_get_last_message();
1813 1813
         if(empty($sqlmsg)) return false;
1814 1814
         global $app_strings;
1815 1815
         if (empty($app_strings)
1816
-		    or !isset($app_strings['ERR_MSSQL_DB_CONTEXT'])
1817
-			or !isset($app_strings['ERR_MSSQL_WARNING']) ) {
1816
+            or !isset($app_strings['ERR_MSSQL_DB_CONTEXT'])
1817
+            or !isset($app_strings['ERR_MSSQL_WARNING']) ) {
1818 1818
         //ignore the message from sql-server if $app_strings array is empty. This will happen
1819 1819
         //only if connection if made before language is set.
1820
-		    return false;
1820
+            return false;
1821 1821
         }
1822 1822
 
1823 1823
         $sqlpos = strpos($sqlmsg, 'Changed database context to');
@@ -1826,7 +1826,7 @@  discard block
 block discarded – undo
1826 1826
         if ( $sqlpos !== false || $sqlpos2 !== false || $sqlpos3 !== false ) {
1827 1827
             return false;
1828 1828
         } else {
1829
-        	global $app_strings;
1829
+            global $app_strings;
1830 1830
             //ERR_MSSQL_DB_CONTEXT: localized version of 'Changed database context to' message
1831 1831
             if (empty($app_strings) or !isset($app_strings['ERR_MSSQL_DB_CONTEXT'])) {
1832 1832
                 //ignore the message from sql-server if $app_strings array is empty. This will happen
@@ -1842,7 +1842,7 @@  discard block
 block discarded – undo
1842 1842
         }
1843 1843
 
1844 1844
         if ( strlen($sqlmsg) > 2 ) {
1845
-        	return "SQL Server error: " . $sqlmsg;
1845
+            return "SQL Server error: " . $sqlmsg;
1846 1846
         }
1847 1847
 
1848 1848
         return false;
@@ -2065,7 +2065,7 @@  discard block
 block discarded – undo
2065 2065
     public function installConfig()
2066 2066
     {
2067 2067
         return array(
2068
-        	'LBL_DBCONFIG_MSG3' =>  array(
2068
+            'LBL_DBCONFIG_MSG3' =>  array(
2069 2069
                 "setup_db_database_name" => array("label" => 'LBL_DBCONF_DB_NAME', "required" => true),
2070 2070
             ),
2071 2071
             'LBL_DBCONFIG_MSG2' =>  array(
@@ -2097,8 +2097,8 @@  discard block
 block discarded – undo
2097 2097
      * @return string
2098 2098
      */
2099 2099
 
2100
-	public function getGuidSQL()
2100
+    public function getGuidSQL()
2101 2101
     {
2102
-      	return 'NEWID()';
2102
+            return 'NEWID()';
2103 2103
     }
2104 2104
 }
Please login to merge, or discard this patch.
include/database/DBManager.php 1 patch
Indentation   +3266 added lines, -3266 removed lines patch added patch discarded remove patch
@@ -97,389 +97,389 @@  discard block
 block discarded – undo
97 97
  */
98 98
 abstract class DBManager
99 99
 {
100
-	/**
101
-	 * Name of database
102
-	 * @var resource
103
-	 */
104
-	public $database = null;
105
-
106
-	/**
107
-	 * Indicates whether we should die when we get an error from the DB
108
-	 */
109
-	protected $dieOnError = false;
110
-
111
-	/**
112
-	 * Indicates whether we should html encode the results from a query by default
113
-	 */
114
-	protected $encode = true;
115
-
116
-	/**
117
-	 * Records the execution time of the last query
118
-	 */
119
-	protected $query_time = 0;
120
-
121
-	/**
122
-	 * Last error message from the DB backend
123
-	 */
124
-	protected $last_error = false;
125
-
126
-	/**
127
-	 * Registry of available result sets
128
-	 */
129
-	protected $lastResult;
130
-
131
-	/**
132
-	 * Current query count
133
-	 */
134
-	private static $queryCount = 0;
135
-
136
-	/**
137
-	 * Query threshold limit
138
-	 */
139
-	private static $queryLimit = 0;
140
-
141
-	/**
142
-	 * Array of prepared statements and their correspoding parsed tokens
143
-	 */
144
-	protected $preparedTokens = array();
145
-
146
-	/**
147
-	 * TimeDate instance
148
-	 * @var TimeDate
149
-	 */
150
-	protected $timedate;
151
-
152
-	/**
153
-	 * PHP Logger
154
-	 * @var Logger
155
-	 */
156
-	protected $log;
157
-
158
-	/**
159
-	 * Table descriptions
160
-	 * @var array
161
-	 */
162
-	protected static $table_descriptions = array();
163
-
164
-	/**
165
-	 * Index descriptions
166
-	 * @var array
167
-	 */
168
-	protected static $index_descriptions = array();
169
-
170
-	/**
171
-	 * Maximum length of identifiers
172
-	 * @abstract
173
-	 * @var array
174
-	 */
175
-	protected $maxNameLengths = array(
176
-		'table' => 64,
177
-		'column' => 64,
178
-		'index' => 64,
179
-		'alias' => 64
180
-	);
181
-
182
-	/**
183
-	 * DB driver priority
184
-	 * Higher priority drivers override lower priority ones
185
-	 * @var int
186
-	 */
187
-	public $priority = 0;
188
-
189
-	/**
190
-	 * Driver name label, for install
191
-	 * @absrtact
192
-	 * @var string
193
-	 */
194
-	public $label = '';
195
-
196
-	/**
197
-	 * Type names map
198
-	 * @abstract
199
-	 * @var array
200
-	 */
201
-	protected $type_map = array();
202
-
203
-	/**
204
-	 * Type classification into:
205
-	 * - int
206
-	 * - bool
207
-	 * - float
208
-	 * - date
209
-	 * @abstract
210
-	 * @var array
211
-	 */
212
-	protected $type_class = array(
213
-			'int'      => 'int',
214
-			'double'   => 'float',
215
-			'float'    => 'float',
216
-			'uint'     => 'int',
217
-			'ulong'    => 'bigint',
218
-			'long'     => 'bigint',
219
-			'short'    => 'int',
220
-			'date'     => 'date',
221
-			'datetime' => 'date',
222
-			'datetimecombo' => 'date',
223
-			'time'     => 'time',
224
-			'bool'     => 'bool',
225
-			'tinyint'  => 'int',
226
-			'currency' => 'float',
227
-			'decimal'  => 'float',
228
-			'decimal2' => 'float',
229
-	);
230
-
231
-	/**
232
-	 * Capabilities this DB supports. Supported list:
233
-	 * affected_rows	Can report query affected rows for UPDATE/DELETE
234
-	 * 					implement getAffectedRowCount()
235
-	 * select_rows		Can report row count for SELECT
236
-	 * 					implement getRowCount()
237
-	 * case_sensitive	Supports case-sensitive text columns
238
-	 * fulltext			Supports fulltext search indexes
239
-	 * inline_keys		Supports defining keys together with the table
240
-	 * auto_increment_sequence Autoincrement support implemented as sequence
241
-	 * limit_subquery   Supports LIMIT clauses in subqueries
242
-	 * create_user		Can create users for Sugar
243
-	 * create_db		Can create databases
244
-	 * collation		Supports setting collations
245
-	 * disable_keys     Supports temporarily disabling keys (for upgrades, etc.)
246
-	 *
247
-	 * @abstract
248
-	 * Special cases:
249
-	 * fix:expandDatabase - needs expandDatabase fix, see expandDatabase.php
250
-	 * TODO: verify if we need these cases
251
-	 */
252
-	protected $capabilities = array();
253
-
254
-	/**
255
-	 * Database options
256
-	 * @var array
257
-	 */
258
-	protected $options = array();
100
+    /**
101
+     * Name of database
102
+     * @var resource
103
+     */
104
+    public $database = null;
105
+
106
+    /**
107
+     * Indicates whether we should die when we get an error from the DB
108
+     */
109
+    protected $dieOnError = false;
110
+
111
+    /**
112
+     * Indicates whether we should html encode the results from a query by default
113
+     */
114
+    protected $encode = true;
115
+
116
+    /**
117
+     * Records the execution time of the last query
118
+     */
119
+    protected $query_time = 0;
120
+
121
+    /**
122
+     * Last error message from the DB backend
123
+     */
124
+    protected $last_error = false;
125
+
126
+    /**
127
+     * Registry of available result sets
128
+     */
129
+    protected $lastResult;
130
+
131
+    /**
132
+     * Current query count
133
+     */
134
+    private static $queryCount = 0;
135
+
136
+    /**
137
+     * Query threshold limit
138
+     */
139
+    private static $queryLimit = 0;
140
+
141
+    /**
142
+     * Array of prepared statements and their correspoding parsed tokens
143
+     */
144
+    protected $preparedTokens = array();
145
+
146
+    /**
147
+     * TimeDate instance
148
+     * @var TimeDate
149
+     */
150
+    protected $timedate;
151
+
152
+    /**
153
+     * PHP Logger
154
+     * @var Logger
155
+     */
156
+    protected $log;
157
+
158
+    /**
159
+     * Table descriptions
160
+     * @var array
161
+     */
162
+    protected static $table_descriptions = array();
163
+
164
+    /**
165
+     * Index descriptions
166
+     * @var array
167
+     */
168
+    protected static $index_descriptions = array();
169
+
170
+    /**
171
+     * Maximum length of identifiers
172
+     * @abstract
173
+     * @var array
174
+     */
175
+    protected $maxNameLengths = array(
176
+        'table' => 64,
177
+        'column' => 64,
178
+        'index' => 64,
179
+        'alias' => 64
180
+    );
181
+
182
+    /**
183
+     * DB driver priority
184
+     * Higher priority drivers override lower priority ones
185
+     * @var int
186
+     */
187
+    public $priority = 0;
188
+
189
+    /**
190
+     * Driver name label, for install
191
+     * @absrtact
192
+     * @var string
193
+     */
194
+    public $label = '';
195
+
196
+    /**
197
+     * Type names map
198
+     * @abstract
199
+     * @var array
200
+     */
201
+    protected $type_map = array();
202
+
203
+    /**
204
+     * Type classification into:
205
+     * - int
206
+     * - bool
207
+     * - float
208
+     * - date
209
+     * @abstract
210
+     * @var array
211
+     */
212
+    protected $type_class = array(
213
+            'int'      => 'int',
214
+            'double'   => 'float',
215
+            'float'    => 'float',
216
+            'uint'     => 'int',
217
+            'ulong'    => 'bigint',
218
+            'long'     => 'bigint',
219
+            'short'    => 'int',
220
+            'date'     => 'date',
221
+            'datetime' => 'date',
222
+            'datetimecombo' => 'date',
223
+            'time'     => 'time',
224
+            'bool'     => 'bool',
225
+            'tinyint'  => 'int',
226
+            'currency' => 'float',
227
+            'decimal'  => 'float',
228
+            'decimal2' => 'float',
229
+    );
230
+
231
+    /**
232
+     * Capabilities this DB supports. Supported list:
233
+     * affected_rows	Can report query affected rows for UPDATE/DELETE
234
+     * 					implement getAffectedRowCount()
235
+     * select_rows		Can report row count for SELECT
236
+     * 					implement getRowCount()
237
+     * case_sensitive	Supports case-sensitive text columns
238
+     * fulltext			Supports fulltext search indexes
239
+     * inline_keys		Supports defining keys together with the table
240
+     * auto_increment_sequence Autoincrement support implemented as sequence
241
+     * limit_subquery   Supports LIMIT clauses in subqueries
242
+     * create_user		Can create users for Sugar
243
+     * create_db		Can create databases
244
+     * collation		Supports setting collations
245
+     * disable_keys     Supports temporarily disabling keys (for upgrades, etc.)
246
+     *
247
+     * @abstract
248
+     * Special cases:
249
+     * fix:expandDatabase - needs expandDatabase fix, see expandDatabase.php
250
+     * TODO: verify if we need these cases
251
+     */
252
+    protected $capabilities = array();
253
+
254
+    /**
255
+     * Database options
256
+     * @var array
257
+     */
258
+    protected $options = array();
259 259
 
260 260
     /**
261 261
      * Create DB Driver
262 262
      */
263
-	public function __construct()
264
-	{
265
-		$this->timedate = TimeDate::getInstance();
266
-		$this->log = isset($GLOBALS['log']) ? $GLOBALS['log'] : null;
267
-		$this->helper = $this; // compatibility
268
-	}
263
+    public function __construct()
264
+    {
265
+        $this->timedate = TimeDate::getInstance();
266
+        $this->log = isset($GLOBALS['log']) ? $GLOBALS['log'] : null;
267
+        $this->helper = $this; // compatibility
268
+    }
269 269
 
270 270
     /**
271 271
      * Wrapper for those trying to access the private and protected class members directly
272 272
      * @param string $p var name
273 273
      * @return mixed
274 274
      */
275
-	public function __get($p)
276
-	{
277
-		$this->log->info('Call to DBManager::$'.$p.' is deprecated');
278
-		return $this->$p;
279
-	}
280
-
281
-	/**
282
-	 * Returns the current database handle
283
-	 * @return resource
284
-	 */
285
-	public function getDatabase()
286
-	{
287
-		$this->checkConnection();
288
-		return $this->database;
289
-	}
290
-
291
-	/**
292
-	 * Returns this instance's DBHelper
293
-	 * Actually now returns $this
294
-	 * @deprecated
295
-	 * @return DBManager
296
-	 */
297
-	public function getHelper()
298
-	{
299
-		return $this;
300
-	}
301
-
302
-	/**
303
-	 * Checks for error happening in the database
304
-	 *
305
-	 * @param  string $msg        message to prepend to the error message
306
-	 * @param  bool   $dieOnError true if we want to die immediately on error
307
-	 * @return bool True if there was an error
308
-	 */
309
-	public function checkError($msg = '', $dieOnError = false)
310
-	{
311
-		if (empty($this->database)) {
312
-			$this->registerError($msg, "Database Is Not Connected", $dieOnError);
313
-			return true;
314
-		}
315
-
316
-		$dberror = $this->lastDbError();
317
-		if($dberror === false) {
318
-    		$this->last_error = false;
319
-	    	return false;
320
-		}
321
-		$this->registerError($msg, $dberror, $dieOnError);
275
+    public function __get($p)
276
+    {
277
+        $this->log->info('Call to DBManager::$'.$p.' is deprecated');
278
+        return $this->$p;
279
+    }
280
+
281
+    /**
282
+     * Returns the current database handle
283
+     * @return resource
284
+     */
285
+    public function getDatabase()
286
+    {
287
+        $this->checkConnection();
288
+        return $this->database;
289
+    }
290
+
291
+    /**
292
+     * Returns this instance's DBHelper
293
+     * Actually now returns $this
294
+     * @deprecated
295
+     * @return DBManager
296
+     */
297
+    public function getHelper()
298
+    {
299
+        return $this;
300
+    }
301
+
302
+    /**
303
+     * Checks for error happening in the database
304
+     *
305
+     * @param  string $msg        message to prepend to the error message
306
+     * @param  bool   $dieOnError true if we want to die immediately on error
307
+     * @return bool True if there was an error
308
+     */
309
+    public function checkError($msg = '', $dieOnError = false)
310
+    {
311
+        if (empty($this->database)) {
312
+            $this->registerError($msg, "Database Is Not Connected", $dieOnError);
313
+            return true;
314
+        }
315
+
316
+        $dberror = $this->lastDbError();
317
+        if($dberror === false) {
318
+            $this->last_error = false;
319
+            return false;
320
+        }
321
+        $this->registerError($msg, $dberror, $dieOnError);
322 322
         return true;
323
-	}
324
-
325
-	/**
326
-	 * Register database error
327
-	 * If die-on-error flag is set, logs the message and dies,
328
-	 * otherwise sets last_error to the message
329
-	 * @param string $userMessage Message from function user
330
-	 * @param string $message Message from SQL driver
331
-	 * @param bool $dieOnError
332
-	 */
333
-	protected function registerError($userMessage, $message, $dieOnError = false)
334
-	{
335
-		if(!empty($message)) {
336
-			if(!empty($userMessage)) {
337
-				$message = "$userMessage: $message";
338
-			}
339
-			if(empty($message)) {
340
-			    $message = "Database error";
341
-			}
342
-			$this->log->fatal($message);
343
-			if ($dieOnError || $this->dieOnError) {
344
-				if(isset($GLOBALS['app_strings']['ERR_DB_FAIL'])) {
345
-					sugar_die($GLOBALS['app_strings']['ERR_DB_FAIL']);
346
-				} else {
347
-					sugar_die("Database error. Please check suitecrm.log for details.");
348
-				}
349
-			} else {
350
-				$this->last_error = $message;
351
-			}
352
-		}
353
-	}
354
-
355
-	/**
356
-	 * Return DB error message for the last query executed
357
-	 * @return string Last error message
358
-	 */
359
-	public function lastError()
360
-	{
361
-		return $this->last_error;
362
-	}
363
-
364
-	/**
365
-	 * This method is called by every method that runs a query.
366
-	 * If slow query dumping is turned on and the query time is beyond
367
-	 * the time limit, we will log the query. This function may do
368
-	 * additional reporting or log in a different area in the future.
369
-	 *
370
-	 * @param  string  $query query to log
371
-	 * @return boolean true if the query was logged, false otherwise
372
-	 */
373
-	protected function dump_slow_queries($query)
374
-	{
375
-		global $sugar_config;
376
-
377
-		$do_the_dump = isset($sugar_config['dump_slow_queries'])
378
-			? $sugar_config['dump_slow_queries'] : false;
379
-		$slow_query_time_msec = isset($sugar_config['slow_query_time_msec'])
380
-			? $sugar_config['slow_query_time_msec'] : 5000;
381
-
382
-		if($do_the_dump) {
383
-			if($slow_query_time_msec < ($this->query_time * 1000)) {
384
-				// Then log both the query and the query time
385
-				$this->log->fatal('Slow Query (time:'.$this->query_time."\n".$query);
386
-				return true;
387
-			}
388
-		}
389
-		return false;
390
-	}
323
+    }
324
+
325
+    /**
326
+     * Register database error
327
+     * If die-on-error flag is set, logs the message and dies,
328
+     * otherwise sets last_error to the message
329
+     * @param string $userMessage Message from function user
330
+     * @param string $message Message from SQL driver
331
+     * @param bool $dieOnError
332
+     */
333
+    protected function registerError($userMessage, $message, $dieOnError = false)
334
+    {
335
+        if(!empty($message)) {
336
+            if(!empty($userMessage)) {
337
+                $message = "$userMessage: $message";
338
+            }
339
+            if(empty($message)) {
340
+                $message = "Database error";
341
+            }
342
+            $this->log->fatal($message);
343
+            if ($dieOnError || $this->dieOnError) {
344
+                if(isset($GLOBALS['app_strings']['ERR_DB_FAIL'])) {
345
+                    sugar_die($GLOBALS['app_strings']['ERR_DB_FAIL']);
346
+                } else {
347
+                    sugar_die("Database error. Please check suitecrm.log for details.");
348
+                }
349
+            } else {
350
+                $this->last_error = $message;
351
+            }
352
+        }
353
+    }
354
+
355
+    /**
356
+     * Return DB error message for the last query executed
357
+     * @return string Last error message
358
+     */
359
+    public function lastError()
360
+    {
361
+        return $this->last_error;
362
+    }
363
+
364
+    /**
365
+     * This method is called by every method that runs a query.
366
+     * If slow query dumping is turned on and the query time is beyond
367
+     * the time limit, we will log the query. This function may do
368
+     * additional reporting or log in a different area in the future.
369
+     *
370
+     * @param  string  $query query to log
371
+     * @return boolean true if the query was logged, false otherwise
372
+     */
373
+    protected function dump_slow_queries($query)
374
+    {
375
+        global $sugar_config;
376
+
377
+        $do_the_dump = isset($sugar_config['dump_slow_queries'])
378
+            ? $sugar_config['dump_slow_queries'] : false;
379
+        $slow_query_time_msec = isset($sugar_config['slow_query_time_msec'])
380
+            ? $sugar_config['slow_query_time_msec'] : 5000;
381
+
382
+        if($do_the_dump) {
383
+            if($slow_query_time_msec < ($this->query_time * 1000)) {
384
+                // Then log both the query and the query time
385
+                $this->log->fatal('Slow Query (time:'.$this->query_time."\n".$query);
386
+                return true;
387
+            }
388
+        }
389
+        return false;
390
+    }
391 391
 
392 392
 /**
393
-	* Scans order by to ensure that any field being ordered by is.
394
-	*
395
-	* It will throw a warning error to the log file - fatal if slow query logging is enabled
396
-	*
397
-	* @param  string $sql         query to be run
398
-	* @param  bool   $object_name optional, object to look up indices in
399
-	* @return bool   true if an index is found false otherwise
400
-	*/
393
+ * Scans order by to ensure that any field being ordered by is.
394
+ *
395
+ * It will throw a warning error to the log file - fatal if slow query logging is enabled
396
+ *
397
+ * @param  string $sql         query to be run
398
+ * @param  bool   $object_name optional, object to look up indices in
399
+ * @return bool   true if an index is found false otherwise
400
+ */
401 401
 protected function checkQuery($sql, $object_name = false)
402 402
 {
403
-	$match = array();
404
-	preg_match_all("'.* FROM ([^ ]*).* ORDER BY (.*)'is", $sql, $match);
405
-	$indices = false;
406
-	if (!empty($match[1][0]))
407
-		$table = $match[1][0];
408
-	else
409
-		return false;
410
-
411
-	if (!empty($object_name) && !empty($GLOBALS['dictionary'][$object_name]))
412
-		$indices = $GLOBALS['dictionary'][$object_name]['indices'];
413
-
414
-	if (empty($indices)) {
415
-		foreach ( $GLOBALS['dictionary'] as $current ) {
416
-			if ($current['table'] == $table){
417
-				$indices = $current['indices'];
418
-				break;
419
-			}
420
-		}
421
-	}
422
-	if (empty($indices)) {
423
-		$this->log->warn('CHECK QUERY: Could not find index definitions for table ' . $table);
424
-		return false;
425
-	}
426
-	if (!empty($match[2][0])) {
427
-		$orderBys = explode(' ', $match[2][0]);
428
-		foreach ($orderBys as $orderBy){
429
-			$orderBy = trim($orderBy);
430
-			if (empty($orderBy))
431
-				continue;
432
-			$orderBy = strtolower($orderBy);
433
-			if ($orderBy == 'asc' || $orderBy == 'desc')
434
-				continue;
435
-
436
-			$orderBy = str_replace(array($table . '.', ','), '', $orderBy);
437
-
438
-			foreach ($indices as $index)
439
-				if (empty($index['db']) || $index['db'] == $this->dbType)
440
-					foreach ($index['fields'] as $field)
441
-						if ($field == $orderBy)
442
-							return true;
443
-
444
-			$warning = 'Missing Index For Order By Table: ' . $table . ' Order By:' . $orderBy ;
445
-			if (!empty($GLOBALS['sugar_config']['dump_slow_queries']))
446
-				$this->log->fatal('CHECK QUERY:' .$warning);
447
-			else
448
-				$this->log->warn('CHECK QUERY:' .$warning);
449
-		}
450
-	}
451
-	return false;
452
-	}
453
-
454
-	/**
455
-	 * Returns the time the last query took to execute
456
-	 *
457
-	 * @return int
458
-	 */
459
-	public function getQueryTime()
460
-	{
461
-		return $this->query_time;
462
-	}
463
-
464
-	/**
465
-	 * Checks the current connection; if it is not connected then reconnect
466
-	 */
467
-	public function checkConnection()
468
-	{
469
-		$this->last_error = '';
470
-		if (!isset($this->database))
471
-			$this->connect();
472
-	}
473
-
474
-	/**
475
-	 * Sets the dieOnError value
476
-	 *
477
-	 * @param bool $value
478
-	 */
479
-	public function setDieOnError($value)
480
-	{
481
-		$this->dieOnError = $value;
482
-	}
403
+    $match = array();
404
+    preg_match_all("'.* FROM ([^ ]*).* ORDER BY (.*)'is", $sql, $match);
405
+    $indices = false;
406
+    if (!empty($match[1][0]))
407
+        $table = $match[1][0];
408
+    else
409
+        return false;
410
+
411
+    if (!empty($object_name) && !empty($GLOBALS['dictionary'][$object_name]))
412
+        $indices = $GLOBALS['dictionary'][$object_name]['indices'];
413
+
414
+    if (empty($indices)) {
415
+        foreach ( $GLOBALS['dictionary'] as $current ) {
416
+            if ($current['table'] == $table){
417
+                $indices = $current['indices'];
418
+                break;
419
+            }
420
+        }
421
+    }
422
+    if (empty($indices)) {
423
+        $this->log->warn('CHECK QUERY: Could not find index definitions for table ' . $table);
424
+        return false;
425
+    }
426
+    if (!empty($match[2][0])) {
427
+        $orderBys = explode(' ', $match[2][0]);
428
+        foreach ($orderBys as $orderBy){
429
+            $orderBy = trim($orderBy);
430
+            if (empty($orderBy))
431
+                continue;
432
+            $orderBy = strtolower($orderBy);
433
+            if ($orderBy == 'asc' || $orderBy == 'desc')
434
+                continue;
435
+
436
+            $orderBy = str_replace(array($table . '.', ','), '', $orderBy);
437
+
438
+            foreach ($indices as $index)
439
+                if (empty($index['db']) || $index['db'] == $this->dbType)
440
+                    foreach ($index['fields'] as $field)
441
+                        if ($field == $orderBy)
442
+                            return true;
443
+
444
+            $warning = 'Missing Index For Order By Table: ' . $table . ' Order By:' . $orderBy ;
445
+            if (!empty($GLOBALS['sugar_config']['dump_slow_queries']))
446
+                $this->log->fatal('CHECK QUERY:' .$warning);
447
+            else
448
+                $this->log->warn('CHECK QUERY:' .$warning);
449
+        }
450
+    }
451
+    return false;
452
+    }
453
+
454
+    /**
455
+     * Returns the time the last query took to execute
456
+     *
457
+     * @return int
458
+     */
459
+    public function getQueryTime()
460
+    {
461
+        return $this->query_time;
462
+    }
463
+
464
+    /**
465
+     * Checks the current connection; if it is not connected then reconnect
466
+     */
467
+    public function checkConnection()
468
+    {
469
+        $this->last_error = '';
470
+        if (!isset($this->database))
471
+            $this->connect();
472
+    }
473
+
474
+    /**
475
+     * Sets the dieOnError value
476
+     *
477
+     * @param bool $value
478
+     */
479
+    public function setDieOnError($value)
480
+    {
481
+        $this->dieOnError = $value;
482
+    }
483 483
 
484 484
     /**
485 485
      * Implements a generic insert for any bean.
@@ -488,67 +488,67 @@  discard block
 block discarded – undo
488 488
      * @return bool query result
489 489
      *
490 490
      */
491
-	public function insert(SugarBean $bean)
492
-	{
493
-		$sql = $this->insertSQL($bean);
494
-		$tablename =  $bean->getTableName();
495
-		$msg = "Error inserting into table: $tablename:";
496
-		return $this->query($sql,true,$msg);
497
-	}
498
-
499
-	/**
500
-	 * Insert data into table by parameter definition
501
-	 * @param string $table Table name
502
-	 * @param array $field_defs Definitions in vardef-like format
503
-	 * @param array $data Key/value to insert
504
-	 * @param array $field_map Fields map from SugarBean
505
-	 * @param bool $execute Execute or return query?
491
+    public function insert(SugarBean $bean)
492
+    {
493
+        $sql = $this->insertSQL($bean);
494
+        $tablename =  $bean->getTableName();
495
+        $msg = "Error inserting into table: $tablename:";
496
+        return $this->query($sql,true,$msg);
497
+    }
498
+
499
+    /**
500
+     * Insert data into table by parameter definition
501
+     * @param string $table Table name
502
+     * @param array $field_defs Definitions in vardef-like format
503
+     * @param array $data Key/value to insert
504
+     * @param array $field_map Fields map from SugarBean
505
+     * @param bool $execute Execute or return query?
506 506
      * @return bool query result
507 507
      */
508
-	public function insertParams($table, $field_defs, $data, $field_map = null, $execute = true)
509
-	{
510
-		$values = array();
511
-		foreach ($field_defs as $field => $fieldDef)
512
-		{
513
-			if (isset($fieldDef['source']) && $fieldDef['source'] != 'db')  continue;
514
-			//custom fields handle there save seperatley
515
-			if(!empty($field_map) && !empty($field_map[$field]['custom_type'])) continue;
516
-
517
-			if(isset($data[$field])) {
518
-				// clean the incoming value..
519
-				$val = from_html($data[$field]);
520
-			} else {
521
-				if(isset($fieldDef['default']) && strlen($fieldDef['default']) > 0) {
522
-					$val = $fieldDef['default'];
523
-				} else {
524
-					$val = null;
525
-				}
526
-			}
527
-
528
-			//handle auto increment values here - we may have to do something like nextval for oracle
529
-			if (!empty($fieldDef['auto_increment'])) {
530
-				$auto = $this->getAutoIncrementSQL($table, $fieldDef['name']);
531
-				if(!empty($auto)) {
532
-					$values[$field] = $auto;
533
-				}
534
-			} elseif ($fieldDef['name'] == 'deleted') {
535
-				$values['deleted'] = (int)$val;
536
-			} else {
537
-				// need to do some thing about types of values
538
-				if(!is_null($val) || !empty($fieldDef['required'])) {
539
-					$values[$field] = $this->massageValue($val, $fieldDef);
540
-				}
541
-			}
542
-		}
543
-
544
-		if (empty($values))
545
-			return $execute?true:''; // no columns set
546
-
547
-		// get the entire sql
548
-		$query = "INSERT INTO $table (".implode(",", array_keys($values)).")
508
+    public function insertParams($table, $field_defs, $data, $field_map = null, $execute = true)
509
+    {
510
+        $values = array();
511
+        foreach ($field_defs as $field => $fieldDef)
512
+        {
513
+            if (isset($fieldDef['source']) && $fieldDef['source'] != 'db')  continue;
514
+            //custom fields handle there save seperatley
515
+            if(!empty($field_map) && !empty($field_map[$field]['custom_type'])) continue;
516
+
517
+            if(isset($data[$field])) {
518
+                // clean the incoming value..
519
+                $val = from_html($data[$field]);
520
+            } else {
521
+                if(isset($fieldDef['default']) && strlen($fieldDef['default']) > 0) {
522
+                    $val = $fieldDef['default'];
523
+                } else {
524
+                    $val = null;
525
+                }
526
+            }
527
+
528
+            //handle auto increment values here - we may have to do something like nextval for oracle
529
+            if (!empty($fieldDef['auto_increment'])) {
530
+                $auto = $this->getAutoIncrementSQL($table, $fieldDef['name']);
531
+                if(!empty($auto)) {
532
+                    $values[$field] = $auto;
533
+                }
534
+            } elseif ($fieldDef['name'] == 'deleted') {
535
+                $values['deleted'] = (int)$val;
536
+            } else {
537
+                // need to do some thing about types of values
538
+                if(!is_null($val) || !empty($fieldDef['required'])) {
539
+                    $values[$field] = $this->massageValue($val, $fieldDef);
540
+                }
541
+            }
542
+        }
543
+
544
+        if (empty($values))
545
+            return $execute?true:''; // no columns set
546
+
547
+        // get the entire sql
548
+        $query = "INSERT INTO $table (".implode(",", array_keys($values)).")
549 549
 					VALUES (".implode(",", $values).")";
550
-		return $execute?$this->query($query):$query;
551
-	}
550
+        return $execute?$this->query($query):$query;
551
+    }
552 552
 
553 553
     /**
554 554
      * Implements a generic update for any bean
@@ -560,13 +560,13 @@  discard block
 block discarded – undo
560 560
      * @return bool query result
561 561
      *
562 562
      */
563
-	public function update(SugarBean $bean, array $where = array())
564
-	{
565
-		$sql = $this->updateSQL($bean, $where);
566
-		$tablename = $bean->getTableName();
567
-		$msg = "Error updating table: $tablename:";
568
-		return $this->query($sql,true,$msg);
569
-	}
563
+    public function update(SugarBean $bean, array $where = array())
564
+    {
565
+        $sql = $this->updateSQL($bean, $where);
566
+        $tablename = $bean->getTableName();
567
+        $msg = "Error updating table: $tablename:";
568
+        return $this->query($sql,true,$msg);
569
+    }
570 570
 
571 571
     /**
572 572
      * Implements a generic delete for any bean identified by id
@@ -577,215 +577,215 @@  discard block
 block discarded – undo
577 577
      * If where is not passed, it defaults to id of table
578 578
      * @return bool query result
579 579
      */
580
-	public function delete(SugarBean $bean, array $where = array())
581
-	{
582
-		$sql = $this->deleteSQL($bean, $where);
583
-		$tableName = $bean->getTableName();
584
-		$msg = "Error deleting from table: ".$tableName. ":";
585
-		return $this->query($sql,true,$msg);
586
-	}
587
-
588
-	/**
589
-	 * Implements a generic retrieve for any bean identified by id
590
-	 *
591
-	 * If we want to pass multiple values for a name, pass it as an array
592
-	 * If where is not passed, it defaults to id of table
593
-	 *
594
-	 * @param  SugarBean   $bean  Sugarbean instance
595
-	 * @param  array    $where values with the keys as names of fields.
596
-	 * @return resource result from the query
597
-	 */
598
-	public function retrieve(SugarBean $bean, array $where = array())
599
-	{
600
-		$sql = $this->retrieveSQL($bean, $where);
601
-		$tableName = $bean->getTableName();
602
-		$msg = "Error retriving values from table:".$tableName. ":";
603
-		return $this->query($sql,true,$msg);
604
-	}
605
-
606
-	/**
607
-	 * Implements a generic retrieve for a collection of beans.
608
-	 *
609
-	 * These beans will be joined in the sql by the key attribute of field defs.
610
-	 * Currently, this function does support outer joins.
611
-	 *
612
-	 * @param  array $beans Sugarbean instance(s)
613
-	 * @param  array $cols  columns to be returned with the keys as names of bean as identified by
614
-	 * get_class of bean. Values of this array is the array of fieldDefs to be returned for a bean.
615
-	 * If an empty array is passed, all columns are selected.
616
-	 * @param  array $where  values with the keys as names of bean as identified by get_class of bean
617
-	 * Each value at the first level is an array of values for that bean identified by name of fields.
618
-	 * If we want to pass multiple values for a name, pass it as an array
619
-	 * If where is not passed, all the rows will be returned.
620
-	 * @return resource
621
-	 */
622
-	public function retrieveView(array $beans, array $cols = array(), array $where = array())
623
-	{
624
-		$sql = $this->retrieveViewSQL($beans, $cols, $where);
625
-		$msg = "Error retriving values from View Collection:";
626
-		return $this->query($sql,true,$msg);
627
-	}
628
-
629
-
630
-	/**
631
-	 * Implements creation of a db table for a bean.
632
-	 *
633
-	 * NOTE: does not handle out-of-table constraints, use createConstraintSQL for that
634
-	 * @param SugarBean $bean  Sugarbean instance
635
-	 */
636
-	public function createTable(SugarBean $bean)
637
-	{
638
-		$sql = $this->createTableSQL($bean);
639
-		$tablename = $bean->getTableName();
640
-		$msg = "Error creating table: $tablename:";
641
-		$this->query($sql,true,$msg);
642
-		if(!$this->supports("inline_keys")) {
643
-		// handle constraints and indices
644
-			$indicesArr = $this->createConstraintSql($bean);
645
-			if (count($indicesArr) > 0)
646
-				foreach ($indicesArr as $indexSql)
647
-					$this->query($indexSql, true, $msg);
648
-		}
649
-	}
650
-
651
-	/**
652
-	 * returns SQL to create constraints or indices
653
-	 *
654
-	 * @param  SugarBean $bean SugarBean instance
655
-	 * @return array list of SQL statements
656
-	 */
657
-	protected function createConstraintSql(SugarBean $bean)
658
-	{
659
-		return $this->getConstraintSql($bean->getIndices(), $bean->getTableName());
660
-	}
661
-
662
-	/**
663
-	 * Implements creation of a db table
664
-	 *
665
-	 * @param string $tablename
666
-	 * @param array  $fieldDefs  Field definitions, in vardef format
667
-	 * @param array  $indices    Index definitions, in vardef format
668
-	 * @param string $engine    Engine parameter, used for MySQL engine so far
580
+    public function delete(SugarBean $bean, array $where = array())
581
+    {
582
+        $sql = $this->deleteSQL($bean, $where);
583
+        $tableName = $bean->getTableName();
584
+        $msg = "Error deleting from table: ".$tableName. ":";
585
+        return $this->query($sql,true,$msg);
586
+    }
587
+
588
+    /**
589
+     * Implements a generic retrieve for any bean identified by id
590
+     *
591
+     * If we want to pass multiple values for a name, pass it as an array
592
+     * If where is not passed, it defaults to id of table
593
+     *
594
+     * @param  SugarBean   $bean  Sugarbean instance
595
+     * @param  array    $where values with the keys as names of fields.
596
+     * @return resource result from the query
597
+     */
598
+    public function retrieve(SugarBean $bean, array $where = array())
599
+    {
600
+        $sql = $this->retrieveSQL($bean, $where);
601
+        $tableName = $bean->getTableName();
602
+        $msg = "Error retriving values from table:".$tableName. ":";
603
+        return $this->query($sql,true,$msg);
604
+    }
605
+
606
+    /**
607
+     * Implements a generic retrieve for a collection of beans.
608
+     *
609
+     * These beans will be joined in the sql by the key attribute of field defs.
610
+     * Currently, this function does support outer joins.
611
+     *
612
+     * @param  array $beans Sugarbean instance(s)
613
+     * @param  array $cols  columns to be returned with the keys as names of bean as identified by
614
+     * get_class of bean. Values of this array is the array of fieldDefs to be returned for a bean.
615
+     * If an empty array is passed, all columns are selected.
616
+     * @param  array $where  values with the keys as names of bean as identified by get_class of bean
617
+     * Each value at the first level is an array of values for that bean identified by name of fields.
618
+     * If we want to pass multiple values for a name, pass it as an array
619
+     * If where is not passed, all the rows will be returned.
620
+     * @return resource
621
+     */
622
+    public function retrieveView(array $beans, array $cols = array(), array $where = array())
623
+    {
624
+        $sql = $this->retrieveViewSQL($beans, $cols, $where);
625
+        $msg = "Error retriving values from View Collection:";
626
+        return $this->query($sql,true,$msg);
627
+    }
628
+
629
+
630
+    /**
631
+     * Implements creation of a db table for a bean.
632
+     *
633
+     * NOTE: does not handle out-of-table constraints, use createConstraintSQL for that
634
+     * @param SugarBean $bean  Sugarbean instance
635
+     */
636
+    public function createTable(SugarBean $bean)
637
+    {
638
+        $sql = $this->createTableSQL($bean);
639
+        $tablename = $bean->getTableName();
640
+        $msg = "Error creating table: $tablename:";
641
+        $this->query($sql,true,$msg);
642
+        if(!$this->supports("inline_keys")) {
643
+        // handle constraints and indices
644
+            $indicesArr = $this->createConstraintSql($bean);
645
+            if (count($indicesArr) > 0)
646
+                foreach ($indicesArr as $indexSql)
647
+                    $this->query($indexSql, true, $msg);
648
+        }
649
+    }
650
+
651
+    /**
652
+     * returns SQL to create constraints or indices
653
+     *
654
+     * @param  SugarBean $bean SugarBean instance
655
+     * @return array list of SQL statements
656
+     */
657
+    protected function createConstraintSql(SugarBean $bean)
658
+    {
659
+        return $this->getConstraintSql($bean->getIndices(), $bean->getTableName());
660
+    }
661
+
662
+    /**
663
+     * Implements creation of a db table
664
+     *
665
+     * @param string $tablename
666
+     * @param array  $fieldDefs  Field definitions, in vardef format
667
+     * @param array  $indices    Index definitions, in vardef format
668
+     * @param string $engine    Engine parameter, used for MySQL engine so far
669 669
      * @todo: refactor engine param to be more generic
670 670
      * @return bool success value
671 671
      */
672
-	public function createTableParams($tablename, $fieldDefs, $indices, $engine = null)
673
-	{
674
-		if (!empty($fieldDefs)) {
675
-			$sql = $this->createTableSQLParams($tablename, $fieldDefs, $indices, $engine);
676
-			$res = true;
677
-			if ($sql) {
678
-				$msg = "Error creating table: $tablename";
679
-				$res = ($res and $this->query($sql,true,$msg));
680
-			}
681
-			if(!$this->supports("inline_keys")) {
682
-				// handle constraints and indices
683
-				$indicesArr = $this->getConstraintSql($indices, $tablename);
684
-				if (count($indicesArr) > 0)
685
-					foreach ($indicesArr as $indexSql)
686
-						$res = ($res and $this->query($indexSql, true, "Error creating indexes"));
687
-			}
688
-			return $res;
689
-		}
690
-		return false;
691
-	}
692
-
693
-	/**
694
-	 * Implements repair of a db table for a bean.
695
-	 *
696
-	 * @param  SugarBean $bean    SugarBean instance
697
-	 * @param  bool   $execute true if we want the action to take place, false if we just want the sql returned
698
-	 * @return string SQL statement or empty string, depending upon $execute
699
-	 */
700
-	public function repairTable(SugarBean $bean, $execute = true)
701
-	{
702
-		$indices   = $bean->getIndices();
703
-		$fielddefs = $bean->getFieldDefinitions();
704
-		$tablename = $bean->getTableName();
705
-
706
-		//Clean the indexes to prevent duplicate definitions
707
-		$new_index = array();
708
-		foreach($indices as $ind_def){
709
-			$new_index[$ind_def['name']] = $ind_def;
710
-		}
711
-		//jc: added this for beans that do not actually have a table, namely
712
-		//ForecastOpportunities
713
-		if($tablename == 'does_not_exist' || $tablename == '')
714
-			return '';
715
-
716
-		global $dictionary;
717
-		$engine=null;
718
-		if (isset($dictionary[$bean->getObjectName()]['engine']) && !empty($dictionary[$bean->getObjectName()]['engine']) )
719
-			$engine = $dictionary[$bean->getObjectName()]['engine'];
720
-
721
-		return $this->repairTableParams($tablename, $fielddefs,$new_index,$execute,$engine);
722
-	}
723
-
724
-	/**
725
-	 * Can this field be null?
726
-	 * Auto-increment and ID fields can not be null
727
-	 * @param array $vardef
672
+    public function createTableParams($tablename, $fieldDefs, $indices, $engine = null)
673
+    {
674
+        if (!empty($fieldDefs)) {
675
+            $sql = $this->createTableSQLParams($tablename, $fieldDefs, $indices, $engine);
676
+            $res = true;
677
+            if ($sql) {
678
+                $msg = "Error creating table: $tablename";
679
+                $res = ($res and $this->query($sql,true,$msg));
680
+            }
681
+            if(!$this->supports("inline_keys")) {
682
+                // handle constraints and indices
683
+                $indicesArr = $this->getConstraintSql($indices, $tablename);
684
+                if (count($indicesArr) > 0)
685
+                    foreach ($indicesArr as $indexSql)
686
+                        $res = ($res and $this->query($indexSql, true, "Error creating indexes"));
687
+            }
688
+            return $res;
689
+        }
690
+        return false;
691
+    }
692
+
693
+    /**
694
+     * Implements repair of a db table for a bean.
695
+     *
696
+     * @param  SugarBean $bean    SugarBean instance
697
+     * @param  bool   $execute true if we want the action to take place, false if we just want the sql returned
698
+     * @return string SQL statement or empty string, depending upon $execute
699
+     */
700
+    public function repairTable(SugarBean $bean, $execute = true)
701
+    {
702
+        $indices   = $bean->getIndices();
703
+        $fielddefs = $bean->getFieldDefinitions();
704
+        $tablename = $bean->getTableName();
705
+
706
+        //Clean the indexes to prevent duplicate definitions
707
+        $new_index = array();
708
+        foreach($indices as $ind_def){
709
+            $new_index[$ind_def['name']] = $ind_def;
710
+        }
711
+        //jc: added this for beans that do not actually have a table, namely
712
+        //ForecastOpportunities
713
+        if($tablename == 'does_not_exist' || $tablename == '')
714
+            return '';
715
+
716
+        global $dictionary;
717
+        $engine=null;
718
+        if (isset($dictionary[$bean->getObjectName()]['engine']) && !empty($dictionary[$bean->getObjectName()]['engine']) )
719
+            $engine = $dictionary[$bean->getObjectName()]['engine'];
720
+
721
+        return $this->repairTableParams($tablename, $fielddefs,$new_index,$execute,$engine);
722
+    }
723
+
724
+    /**
725
+     * Can this field be null?
726
+     * Auto-increment and ID fields can not be null
727
+     * @param array $vardef
728 728
      * @return bool
729 729
      */
730
-	protected function isNullable($vardef)
731
-	{
732
-
733
-		if(isset($vardef['isnull']) && (strtolower($vardef['isnull']) == 'false' || $vardef['isnull'] === false)
734
-			&& !empty($vardef['required'])) {
735
-				/* required + is_null=false => not null */
736
-			return false;
737
-		}
738
-		if(empty($vardef['auto_increment']) && (empty($vardef['type']) || $vardef['type'] != 'id')
739
-					&& (empty($vardef['dbType']) || $vardef['dbType'] != 'id')
740
-					&& (empty($vardef['name']) || ($vardef['name'] != 'id' && $vardef['name'] != 'deleted'))
741
-		) {
742
-			return true;
743
-		}
744
-		return false;
745
-	}
746
-
747
-
748
-	/**
749
-	 * Builds the SQL commands that repair a table structure
750
-	 *
751
-	 * @param  string $tablename
752
-	 * @param  array  $fielddefs Field definitions, in vardef format
753
-	 * @param  array  $indices   Index definitions, in vardef format
754
-	 * @param  bool   $execute   optional, true if we want the queries executed instead of returned
755
-	 * @param  string $engine    optional, MySQL engine
730
+    protected function isNullable($vardef)
731
+    {
732
+
733
+        if(isset($vardef['isnull']) && (strtolower($vardef['isnull']) == 'false' || $vardef['isnull'] === false)
734
+            && !empty($vardef['required'])) {
735
+                /* required + is_null=false => not null */
736
+            return false;
737
+        }
738
+        if(empty($vardef['auto_increment']) && (empty($vardef['type']) || $vardef['type'] != 'id')
739
+                    && (empty($vardef['dbType']) || $vardef['dbType'] != 'id')
740
+                    && (empty($vardef['name']) || ($vardef['name'] != 'id' && $vardef['name'] != 'deleted'))
741
+        ) {
742
+            return true;
743
+        }
744
+        return false;
745
+    }
746
+
747
+
748
+    /**
749
+     * Builds the SQL commands that repair a table structure
750
+     *
751
+     * @param  string $tablename
752
+     * @param  array  $fielddefs Field definitions, in vardef format
753
+     * @param  array  $indices   Index definitions, in vardef format
754
+     * @param  bool   $execute   optional, true if we want the queries executed instead of returned
755
+     * @param  string $engine    optional, MySQL engine
756 756
      * @todo: refactor engine param to be more generic
757 757
      * @return string
758 758
      */
759
-	public function repairTableParams($tablename, $fielddefs,  $indices, $execute = true, $engine = null)
760
-	{
761
-		//jc: had a bug when running the repair if the tablename is blank the repair will
762
-		//fail when it tries to create a repair table
763
-		if ($tablename == '' || empty($fielddefs))
764
-			return '';
765
-
766
-		//if the table does not exist create it and we are done
767
-		$sql = "/* Table : $tablename */\n";
768
-		if (!$this->tableExists($tablename)) {
769
-			$createtablesql = $this->createTableSQLParams($tablename,$fielddefs,$indices,$engine);
770
-			if($execute && $createtablesql){
771
-				$this->createTableParams($tablename,$fielddefs,$indices,$engine);
772
-			}
773
-
774
-			$sql .= "/* MISSING TABLE: {$tablename} */\n";
775
-			$sql .= $createtablesql . "\n";
776
-			return $sql;
777
-		}
778
-
779
-		$compareFieldDefs = $this->get_columns($tablename);
780
-		$compareIndices = $this->get_indices($tablename);
781
-
782
-		$take_action = false;
783
-
784
-		// do column comparisons
785
-		$sql .=	"/*COLUMNS*/\n";
786
-		foreach ($fielddefs as $name => $value) {
787
-			if (isset($value['source']) && $value['source'] != 'db')
788
-				continue;
759
+    public function repairTableParams($tablename, $fielddefs,  $indices, $execute = true, $engine = null)
760
+    {
761
+        //jc: had a bug when running the repair if the tablename is blank the repair will
762
+        //fail when it tries to create a repair table
763
+        if ($tablename == '' || empty($fielddefs))
764
+            return '';
765
+
766
+        //if the table does not exist create it and we are done
767
+        $sql = "/* Table : $tablename */\n";
768
+        if (!$this->tableExists($tablename)) {
769
+            $createtablesql = $this->createTableSQLParams($tablename,$fielddefs,$indices,$engine);
770
+            if($execute && $createtablesql){
771
+                $this->createTableParams($tablename,$fielddefs,$indices,$engine);
772
+            }
773
+
774
+            $sql .= "/* MISSING TABLE: {$tablename} */\n";
775
+            $sql .= $createtablesql . "\n";
776
+            return $sql;
777
+        }
778
+
779
+        $compareFieldDefs = $this->get_columns($tablename);
780
+        $compareIndices = $this->get_indices($tablename);
781
+
782
+        $take_action = false;
783
+
784
+        // do column comparisons
785
+        $sql .=	"/*COLUMNS*/\n";
786
+        foreach ($fielddefs as $name => $value) {
787
+            if (isset($value['source']) && $value['source'] != 'db')
788
+                continue;
789 789
 
790 790
             // Bug #42406. Skipping breaked vardef without type or name
791 791
             if (isset($value['name']) == false || $value['name'] == false)
@@ -799,183 +799,183 @@  discard block
 block discarded – undo
799 799
                 continue;
800 800
             }
801 801
 
802
-			$name = strtolower($value['name']);
803
-			// add or fix the field defs per what the DB is expected to give us back
804
-			$this->massageFieldDef($value,$tablename);
805
-
806
-			$ignorerequired=false;
807
-
808
-			//Do not track requiredness in the DB, auto_increment, ID,
809
-			// and deleted fields are always required in the DB, so don't force those
810
-			if ($this->isNullable($value)) {
811
-				$value['required'] = false;
812
-			}
813
-			//Should match the conditions in DBManager::oneColumnSQLRep for DB required fields, type='id' fields will sometimes
814
-
815
-			//come into this function as 'type' = 'char', 'dbType' = 'id' without required set in $value. Assume they are correct and leave them alone.
816
-			else if (($name == 'id' || $value['type'] == 'id' || (isset($value['dbType']) && $value['dbType'] == 'id'))
817
-				&& (!isset($value['required']) && isset($compareFieldDefs[$name]['required'])))
818
-			{
819
-				$value['required'] = $compareFieldDefs[$name]['required'];
820
-			}
821
-
822
-			if ( !isset($compareFieldDefs[$name]) ) {
823
-				// ok we need this field lets create it
824
-				$sql .=	"/*MISSING IN DATABASE - $name -  ROW*/\n";
825
-				$sql .= $this->addColumnSQL($tablename, $value) .  "\n";
826
-				if ($execute)
827
-					$this->addColumn($tablename, $value);
828
-				$take_action = true;
829
-			} elseif ( !$this->compareVarDefs($compareFieldDefs[$name],$value)) {
830
-				//fields are different lets alter it
831
-				$sql .=	"/*MISMATCH WITH DATABASE - $name -  ROW ";
832
-				foreach($compareFieldDefs[$name] as $rKey => $rValue) {
833
-					$sql .=	"[$rKey] => '$rValue'  ";
834
-				}
835
-				$sql .=	"*/\n";
836
-				$sql .=	"/* VARDEF - $name -  ROW";
837
-				foreach($value as $rKey => $rValue) {
838
-					$sql .=	"[$rKey] => '$rValue'  ";
839
-				}
840
-				$sql .=	"*/\n";
841
-
842
-				//jc: oracle will complain if you try to execute a statement that sets a column to (not) null
843
-				//when it is already (not) null
844
-				if ( isset($value['isnull']) && isset($compareFieldDefs[$name]['isnull']) &&
845
-					$value['isnull'] === $compareFieldDefs[$name]['isnull']) {
846
-					unset($value['required']);
847
-					$ignorerequired=true;
848
-				}
849
-
850
-				//dwheeler: Once a column has been defined as null, we cannot try to force it back to !null
851
-				if ((isset($value['required']) && ($value['required'] === true || $value['required'] == 'true' || $value['required'] === 1))
852
-					&& (empty($compareFieldDefs[$name]['required']) || $compareFieldDefs[$name]['required'] != 'true'))
853
-				{
854
-					$ignorerequired = true;
855
-				}
856
-				$altersql = $this->alterColumnSQL($tablename, $value,$ignorerequired);
857
-				if(is_array($altersql)) {
858
-					$altersql = join("\n", $altersql);
859
-				}
860
-				$sql .= $altersql .  "\n";
861
-				if($execute){
862
-					$this->alterColumn($tablename, $value, $ignorerequired);
863
-				}
864
-				$take_action = true;
865
-			}
866
-		}
867
-
868
-		// do index comparisons
869
-		$sql .=	"/* INDEXES */\n";
870
-		$correctedIndexs = array();
802
+            $name = strtolower($value['name']);
803
+            // add or fix the field defs per what the DB is expected to give us back
804
+            $this->massageFieldDef($value,$tablename);
871 805
 
872
-        $compareIndices_case_insensitive = array();
806
+            $ignorerequired=false;
873 807
 
874
-		// do indices comparisons case-insensitive
875
-		foreach($compareIndices as $k => $value){
876
-			$value['name'] = strtolower($value['name']);
877
-			$compareIndices_case_insensitive[strtolower($k)] = $value;
878
-		}
879
-		$compareIndices = $compareIndices_case_insensitive;
880
-		unset($compareIndices_case_insensitive);
881
-
882
-		foreach ($indices as $value) {
883
-			if (isset($value['source']) && $value['source'] != 'db')
884
-				continue;
885
-
886
-
887
-			$validDBName = $this->getValidDBName($value['name'], true, 'index', true);
888
-			if (isset($compareIndices[$validDBName])) {
889
-				$value['name'] = $validDBName;
890
-			}
891
-		    $name = strtolower($value['name']);
892
-
893
-			//Don't attempt to fix the same index twice in one pass;
894
-			if (isset($correctedIndexs[$name]))
895
-				continue;
896
-
897
-			//don't bother checking primary nothing we can do about them
898
-			if (isset($value['type']) && $value['type'] == 'primary')
899
-				continue;
900
-
901
-			//database helpers do not know how to handle full text indices
902
-			if ($value['type']=='fulltext')
903
-				continue;
904
-
905
-			if ( in_array($value['type'],array('alternate_key','foreign')) )
906
-				$value['type'] = 'index';
907
-
908
-			if ( !isset($compareIndices[$name]) ) {
909
-				//First check if an index exists that doesn't match our name, if so, try to rename it
910
-				$found = false;
911
-				foreach ($compareIndices as $ex_name => $ex_value) {
912
-					if($this->compareVarDefs($ex_value, $value, true)) {
913
-						$found = $ex_name;
914
-						break;
915
-					}
916
-				}
917
-				if ($found) {
918
-					$sql .=	 "/*MISSNAMED INDEX IN DATABASE - $name - $ex_name */\n";
919
-					$rename = $this->renameIndexDefs($ex_value, $value, $tablename);
920
-					if($execute) {
921
-						$this->query($rename, true, "Cannot rename index");
922
-					}
923
-					$sql .= is_array($rename)?join("\n", $rename). "\n":$rename."\n";
924
-
925
-				} else {
926
-					// ok we need this field lets create it
927
-					$sql .=	 "/*MISSING INDEX IN DATABASE - $name -{$value['type']}  ROW */\n";
928
-					$sql .= $this->addIndexes($tablename,array($value), $execute) .  "\n";
929
-				}
930
-				$take_action = true;
931
-				$correctedIndexs[$name] = true;
932
-			} elseif ( !$this->compareVarDefs($compareIndices[$name],$value) ) {
933
-				// fields are different lets alter it
934
-				$sql .=	"/*INDEX MISMATCH WITH DATABASE - $name -  ROW ";
935
-				foreach ($compareIndices[$name] as $n1 => $t1) {
936
-					$sql .=	 "<$n1>";
937
-					if ( $n1 == 'fields' )
938
-						foreach($t1 as $rKey => $rValue)
939
-							$sql .= "[$rKey] => '$rValue'  ";
940
-					else
941
-						$sql .= " $t1 ";
942
-				}
943
-				$sql .=	"*/\n";
944
-				$sql .=	"/* VARDEF - $name -  ROW";
945
-				foreach ($value as $n1 => $t1) {
946
-					$sql .=	"<$n1>";
947
-					if ( $n1 == 'fields' )
948
-						foreach ($t1 as $rKey => $rValue)
949
-							$sql .=	"[$rKey] => '$rValue'  ";
950
-					else
951
-						$sql .= " $t1 ";
952
-				}
953
-				$sql .=	"*/\n";
954
-				$sql .= $this->modifyIndexes($tablename,array($value), $execute) .  "\n";
955
-				$take_action = true;
956
-				$correctedIndexs[$name] = true;
957
-			}
958
-		}
959
-
960
-		return ($take_action === true) ? $sql : '';
961
-	}
808
+            //Do not track requiredness in the DB, auto_increment, ID,
809
+            // and deleted fields are always required in the DB, so don't force those
810
+            if ($this->isNullable($value)) {
811
+                $value['required'] = false;
812
+            }
813
+            //Should match the conditions in DBManager::oneColumnSQLRep for DB required fields, type='id' fields will sometimes
962 814
 
963
-    /**
964
-     * Compares two vardefs
965
-     *
966
-     * @param  array  $fielddef1 This is from the database
967
-     * @param  array  $fielddef2 This is from the vardef
968
-     * @param bool $ignoreName Ignore name-only differences?
969
-     * @return bool   true if they match, false if they don't
970
-     */
971
-	public function compareVarDefs($fielddef1, $fielddef2, $ignoreName = false)
972
-	{
973
-		foreach ( $fielddef1 as $key => $value ) {
974
-			if ($key == 'name' && $ignoreName)
975
-				continue;
976
-            if (isset($fielddef2[$key]))
815
+            //come into this function as 'type' = 'char', 'dbType' = 'id' without required set in $value. Assume they are correct and leave them alone.
816
+            else if (($name == 'id' || $value['type'] == 'id' || (isset($value['dbType']) && $value['dbType'] == 'id'))
817
+                && (!isset($value['required']) && isset($compareFieldDefs[$name]['required'])))
977 818
             {
978
-                if (!is_array($fielddef1[$key]) && !is_array($fielddef2[$key]))
819
+                $value['required'] = $compareFieldDefs[$name]['required'];
820
+            }
821
+
822
+            if ( !isset($compareFieldDefs[$name]) ) {
823
+                // ok we need this field lets create it
824
+                $sql .=	"/*MISSING IN DATABASE - $name -  ROW*/\n";
825
+                $sql .= $this->addColumnSQL($tablename, $value) .  "\n";
826
+                if ($execute)
827
+                    $this->addColumn($tablename, $value);
828
+                $take_action = true;
829
+            } elseif ( !$this->compareVarDefs($compareFieldDefs[$name],$value)) {
830
+                //fields are different lets alter it
831
+                $sql .=	"/*MISMATCH WITH DATABASE - $name -  ROW ";
832
+                foreach($compareFieldDefs[$name] as $rKey => $rValue) {
833
+                    $sql .=	"[$rKey] => '$rValue'  ";
834
+                }
835
+                $sql .=	"*/\n";
836
+                $sql .=	"/* VARDEF - $name -  ROW";
837
+                foreach($value as $rKey => $rValue) {
838
+                    $sql .=	"[$rKey] => '$rValue'  ";
839
+                }
840
+                $sql .=	"*/\n";
841
+
842
+                //jc: oracle will complain if you try to execute a statement that sets a column to (not) null
843
+                //when it is already (not) null
844
+                if ( isset($value['isnull']) && isset($compareFieldDefs[$name]['isnull']) &&
845
+                    $value['isnull'] === $compareFieldDefs[$name]['isnull']) {
846
+                    unset($value['required']);
847
+                    $ignorerequired=true;
848
+                }
849
+
850
+                //dwheeler: Once a column has been defined as null, we cannot try to force it back to !null
851
+                if ((isset($value['required']) && ($value['required'] === true || $value['required'] == 'true' || $value['required'] === 1))
852
+                    && (empty($compareFieldDefs[$name]['required']) || $compareFieldDefs[$name]['required'] != 'true'))
853
+                {
854
+                    $ignorerequired = true;
855
+                }
856
+                $altersql = $this->alterColumnSQL($tablename, $value,$ignorerequired);
857
+                if(is_array($altersql)) {
858
+                    $altersql = join("\n", $altersql);
859
+                }
860
+                $sql .= $altersql .  "\n";
861
+                if($execute){
862
+                    $this->alterColumn($tablename, $value, $ignorerequired);
863
+                }
864
+                $take_action = true;
865
+            }
866
+        }
867
+
868
+        // do index comparisons
869
+        $sql .=	"/* INDEXES */\n";
870
+        $correctedIndexs = array();
871
+
872
+        $compareIndices_case_insensitive = array();
873
+
874
+        // do indices comparisons case-insensitive
875
+        foreach($compareIndices as $k => $value){
876
+            $value['name'] = strtolower($value['name']);
877
+            $compareIndices_case_insensitive[strtolower($k)] = $value;
878
+        }
879
+        $compareIndices = $compareIndices_case_insensitive;
880
+        unset($compareIndices_case_insensitive);
881
+
882
+        foreach ($indices as $value) {
883
+            if (isset($value['source']) && $value['source'] != 'db')
884
+                continue;
885
+
886
+
887
+            $validDBName = $this->getValidDBName($value['name'], true, 'index', true);
888
+            if (isset($compareIndices[$validDBName])) {
889
+                $value['name'] = $validDBName;
890
+            }
891
+            $name = strtolower($value['name']);
892
+
893
+            //Don't attempt to fix the same index twice in one pass;
894
+            if (isset($correctedIndexs[$name]))
895
+                continue;
896
+
897
+            //don't bother checking primary nothing we can do about them
898
+            if (isset($value['type']) && $value['type'] == 'primary')
899
+                continue;
900
+
901
+            //database helpers do not know how to handle full text indices
902
+            if ($value['type']=='fulltext')
903
+                continue;
904
+
905
+            if ( in_array($value['type'],array('alternate_key','foreign')) )
906
+                $value['type'] = 'index';
907
+
908
+            if ( !isset($compareIndices[$name]) ) {
909
+                //First check if an index exists that doesn't match our name, if so, try to rename it
910
+                $found = false;
911
+                foreach ($compareIndices as $ex_name => $ex_value) {
912
+                    if($this->compareVarDefs($ex_value, $value, true)) {
913
+                        $found = $ex_name;
914
+                        break;
915
+                    }
916
+                }
917
+                if ($found) {
918
+                    $sql .=	 "/*MISSNAMED INDEX IN DATABASE - $name - $ex_name */\n";
919
+                    $rename = $this->renameIndexDefs($ex_value, $value, $tablename);
920
+                    if($execute) {
921
+                        $this->query($rename, true, "Cannot rename index");
922
+                    }
923
+                    $sql .= is_array($rename)?join("\n", $rename). "\n":$rename."\n";
924
+
925
+                } else {
926
+                    // ok we need this field lets create it
927
+                    $sql .=	 "/*MISSING INDEX IN DATABASE - $name -{$value['type']}  ROW */\n";
928
+                    $sql .= $this->addIndexes($tablename,array($value), $execute) .  "\n";
929
+                }
930
+                $take_action = true;
931
+                $correctedIndexs[$name] = true;
932
+            } elseif ( !$this->compareVarDefs($compareIndices[$name],$value) ) {
933
+                // fields are different lets alter it
934
+                $sql .=	"/*INDEX MISMATCH WITH DATABASE - $name -  ROW ";
935
+                foreach ($compareIndices[$name] as $n1 => $t1) {
936
+                    $sql .=	 "<$n1>";
937
+                    if ( $n1 == 'fields' )
938
+                        foreach($t1 as $rKey => $rValue)
939
+                            $sql .= "[$rKey] => '$rValue'  ";
940
+                    else
941
+                        $sql .= " $t1 ";
942
+                }
943
+                $sql .=	"*/\n";
944
+                $sql .=	"/* VARDEF - $name -  ROW";
945
+                foreach ($value as $n1 => $t1) {
946
+                    $sql .=	"<$n1>";
947
+                    if ( $n1 == 'fields' )
948
+                        foreach ($t1 as $rKey => $rValue)
949
+                            $sql .=	"[$rKey] => '$rValue'  ";
950
+                    else
951
+                        $sql .= " $t1 ";
952
+                }
953
+                $sql .=	"*/\n";
954
+                $sql .= $this->modifyIndexes($tablename,array($value), $execute) .  "\n";
955
+                $take_action = true;
956
+                $correctedIndexs[$name] = true;
957
+            }
958
+        }
959
+
960
+        return ($take_action === true) ? $sql : '';
961
+    }
962
+
963
+    /**
964
+     * Compares two vardefs
965
+     *
966
+     * @param  array  $fielddef1 This is from the database
967
+     * @param  array  $fielddef2 This is from the vardef
968
+     * @param bool $ignoreName Ignore name-only differences?
969
+     * @return bool   true if they match, false if they don't
970
+     */
971
+    public function compareVarDefs($fielddef1, $fielddef2, $ignoreName = false)
972
+    {
973
+        foreach ( $fielddef1 as $key => $value ) {
974
+            if ($key == 'name' && $ignoreName)
975
+                continue;
976
+            if (isset($fielddef2[$key]))
977
+            {
978
+                if (!is_array($fielddef1[$key]) && !is_array($fielddef2[$key]))
979 979
                 {
980 980
                     if (strtolower($fielddef1[$key]) == strtolower($fielddef2[$key]))
981 981
                     {
@@ -990,64 +990,64 @@  discard block
 block discarded – undo
990 990
                     }
991 991
                 }
992 992
             }
993
-			//Ignore len if its not set in the vardef
994
-			if ($key == 'len' && empty($fielddef2[$key]))
995
-				continue;
993
+            //Ignore len if its not set in the vardef
994
+            if ($key == 'len' && empty($fielddef2[$key]))
995
+                continue;
996 996
             // if the length in db is greather than the vardef, ignore it
997 997
             if ($key == 'len' && ($fielddef1[$key] >= $fielddef2[$key])) {
998 998
                 continue;
999 999
             }
1000
-			return false;
1001
-		}
1002
-
1003
-		return true;
1004
-	}
1005
-
1006
-	/**
1007
-	 * Compare a field in two tables
1008
-	 * @deprecated
1009
-	 * @param  string $name   field name
1010
-	 * @param  string $table1
1011
-	 * @param  string $table2
1012
-	 * @return array  array with keys 'msg','table1','table2'
1013
-	 */
1014
-	public function compareFieldInTables($name, $table1, $table2)
1015
-	{
1016
-		$row1 = $this->describeField($name, $table1);
1017
-		$row2 = $this->describeField($name, $table2);
1018
-		$returnArray = array(
1019
-			'table1' => $row1,
1020
-			'table2' => $row2,
1021
-			'msg'    => 'error',
1022
-			);
1023
-
1024
-		$ignore_filter = array('Key'=>1);
1025
-		if ($row1) {
1026
-			if (!$row2) {
1027
-				// Exists on table1 but not table2
1028
-				$returnArray['msg'] = 'not_exists_table2';
1029
-			}
1030
-			else {
1031
-				if (sizeof($row1) != sizeof($row2)) {
1032
-					$returnArray['msg'] = 'no_match';
1033
-				}
1034
-				else {
1035
-					$returnArray['msg'] = 'match';
1036
-					foreach($row1 as $key => $value){
1037
-						//ignore keys when checking we will check them when we do the index check
1038
-						if( !isset($ignore_filter[$key]) && (!isset($row2[$key]) || $row1[$key] !== $row2[$key])){
1039
-							$returnArray['msg'] = 'no_match';
1040
-						}
1041
-					}
1042
-				}
1043
-			}
1044
-		}
1045
-		else {
1046
-			$returnArray['msg'] = 'not_exists_table1';
1047
-		}
1048
-
1049
-		return $returnArray;
1050
-	}
1000
+            return false;
1001
+        }
1002
+
1003
+        return true;
1004
+    }
1005
+
1006
+    /**
1007
+     * Compare a field in two tables
1008
+     * @deprecated
1009
+     * @param  string $name   field name
1010
+     * @param  string $table1
1011
+     * @param  string $table2
1012
+     * @return array  array with keys 'msg','table1','table2'
1013
+     */
1014
+    public function compareFieldInTables($name, $table1, $table2)
1015
+    {
1016
+        $row1 = $this->describeField($name, $table1);
1017
+        $row2 = $this->describeField($name, $table2);
1018
+        $returnArray = array(
1019
+            'table1' => $row1,
1020
+            'table2' => $row2,
1021
+            'msg'    => 'error',
1022
+            );
1023
+
1024
+        $ignore_filter = array('Key'=>1);
1025
+        if ($row1) {
1026
+            if (!$row2) {
1027
+                // Exists on table1 but not table2
1028
+                $returnArray['msg'] = 'not_exists_table2';
1029
+            }
1030
+            else {
1031
+                if (sizeof($row1) != sizeof($row2)) {
1032
+                    $returnArray['msg'] = 'no_match';
1033
+                }
1034
+                else {
1035
+                    $returnArray['msg'] = 'match';
1036
+                    foreach($row1 as $key => $value){
1037
+                        //ignore keys when checking we will check them when we do the index check
1038
+                        if( !isset($ignore_filter[$key]) && (!isset($row2[$key]) || $row1[$key] !== $row2[$key])){
1039
+                            $returnArray['msg'] = 'no_match';
1040
+                        }
1041
+                    }
1042
+                }
1043
+            }
1044
+        }
1045
+        else {
1046
+            $returnArray['msg'] = 'not_exists_table1';
1047
+        }
1048
+
1049
+        return $returnArray;
1050
+    }
1051 1051
 //
1052 1052
 //    /**
1053 1053
 //     * Compare an index in two different tables
@@ -1097,193 +1097,193 @@  discard block
 block discarded – undo
1097 1097
 //    }
1098 1098
 
1099 1099
 
1100
-	/**
1101
-	 * Creates an index identified by name on the given fields.
1102
-	 *
1103
-	 * @param SugarBean $bean      SugarBean instance
1104
-	 * @param array  $fieldDefs Field definitions, in vardef format
1105
-	 * @param string $name      index name
1106
-	 * @param bool   $unique    optional, true if we want to create an unique index
1100
+    /**
1101
+     * Creates an index identified by name on the given fields.
1102
+     *
1103
+     * @param SugarBean $bean      SugarBean instance
1104
+     * @param array  $fieldDefs Field definitions, in vardef format
1105
+     * @param string $name      index name
1106
+     * @param bool   $unique    optional, true if we want to create an unique index
1107 1107
      * @return bool query result
1108 1108
      */
1109
-	public function createIndex(SugarBean $bean, $fieldDefs, $name, $unique = true)
1110
-	{
1111
-		$sql = $this->createIndexSQL($bean, $fieldDefs, $name, $unique);
1112
-		$tablename = $bean->getTableName();
1113
-		$msg = "Error creating index $name on table: $tablename:";
1114
-		return $this->query($sql,true,$msg);
1115
-	}
1116
-
1117
-	/**
1118
-	 * returns a SQL query that creates the indices as defined in metadata
1119
-	 * @param  array  $indices Assoc array with index definitions from vardefs
1120
-	 * @param  string $table Focus table
1121
-	 * @return array  Array of SQL queries to generate indices
1122
-	 */
1123
-	public function getConstraintSql($indices, $table)
1124
-	{
1125
-		if (!$this->isFieldArray($indices))
1126
-			$indices = array($indices);
1127
-
1128
-		$columns = array();
1129
-
1130
-		foreach ($indices as $index) {
1131
-			if(!empty($index['db']) && $index['db'] != $this->dbType)
1132
-				continue;
1133
-			if (isset($index['source']) && $index['source'] != 'db')
1134
-			continue;
1135
-
1136
-			$sql = $this->add_drop_constraint($table, $index);
1137
-
1138
-			if(!empty($sql)) {
1139
-				$columns[] = $sql;
1140
-			}
1141
-		}
1142
-
1143
-		return $columns;
1144
-	}
1145
-
1146
-	/**
1147
-	 * Adds a new indexes
1148
-	 *
1149
-	 * @param  string $tablename
1150
-	 * @param  array  $indexes   indexes to add
1151
-	 * @param  bool   $execute   true if we want to execute the returned sql statement
1152
-	 * @return string SQL statement
1153
-	 */
1154
-	public function addIndexes($tablename, $indexes, $execute = true)
1155
-	{
1156
-		$alters = $this->getConstraintSql($indexes, $tablename);
1157
-		if ($execute) {
1158
-			foreach($alters as $sql) {
1159
-				$this->query($sql, true, "Error adding index: ");
1160
-			}
1161
-		}
1162
-		if(!empty($alters)) {
1163
-			$sql = join(";\n", $alters).";\n";
1164
-		} else {
1165
-			$sql = '';
1166
-		}
1167
-		return $sql;
1168
-	}
1169
-
1170
-	/**
1171
-	 * Drops indexes
1172
-	 *
1173
-	 * @param  string $tablename
1174
-	 * @param  array  $indexes   indexes to drop
1175
-	 * @param  bool   $execute   true if we want to execute the returned sql statement
1176
-	 * @return string SQL statement
1177
-	 */
1178
-	public function dropIndexes($tablename, $indexes, $execute = true)
1179
-	{
1180
-		$sqls = array();
1181
-		foreach ($indexes as $index) {
1182
-			$name =$index['name'];
1183
-			$sqls[$name] = $this->add_drop_constraint($tablename,$index,true);
1184
-		}
1185
-		if (!empty($sqls) && $execute) {
1186
-			foreach($sqls as $name => $sql) {
1187
-				unset(self::$index_descriptions[$tablename][$name]);
1188
-				$this->query($sql);
1189
-			}
1190
-		}
1191
-		if(!empty($sqls)) {
1192
-			return join(";\n",$sqls).";";
1193
-		} else {
1194
-			return '';
1195
-		}
1196
-	}
1197
-
1198
-	/**
1199
-	 * Modifies indexes
1200
-	 *
1201
-	 * @param  string $tablename
1202
-	 * @param  array  $indexes   indexes to modify
1203
-	 * @param  bool   $execute   true if we want to execute the returned sql statement
1204
-	 * @return string SQL statement
1205
-	 */
1206
-	public function modifyIndexes($tablename, $indexes, $execute = true)
1207
-	{
1208
-		return $this->dropIndexes($tablename, $indexes, $execute)."\n".
1209
-			$this->addIndexes($tablename, $indexes, $execute);
1210
-	}
1211
-
1212
-	/**
1213
-	 * Adds a column to table identified by field def.
1214
-	 *
1215
-	 * @param string $tablename
1216
-	 * @param array  $fieldDefs
1109
+    public function createIndex(SugarBean $bean, $fieldDefs, $name, $unique = true)
1110
+    {
1111
+        $sql = $this->createIndexSQL($bean, $fieldDefs, $name, $unique);
1112
+        $tablename = $bean->getTableName();
1113
+        $msg = "Error creating index $name on table: $tablename:";
1114
+        return $this->query($sql,true,$msg);
1115
+    }
1116
+
1117
+    /**
1118
+     * returns a SQL query that creates the indices as defined in metadata
1119
+     * @param  array  $indices Assoc array with index definitions from vardefs
1120
+     * @param  string $table Focus table
1121
+     * @return array  Array of SQL queries to generate indices
1122
+     */
1123
+    public function getConstraintSql($indices, $table)
1124
+    {
1125
+        if (!$this->isFieldArray($indices))
1126
+            $indices = array($indices);
1127
+
1128
+        $columns = array();
1129
+
1130
+        foreach ($indices as $index) {
1131
+            if(!empty($index['db']) && $index['db'] != $this->dbType)
1132
+                continue;
1133
+            if (isset($index['source']) && $index['source'] != 'db')
1134
+            continue;
1135
+
1136
+            $sql = $this->add_drop_constraint($table, $index);
1137
+
1138
+            if(!empty($sql)) {
1139
+                $columns[] = $sql;
1140
+            }
1141
+        }
1142
+
1143
+        return $columns;
1144
+    }
1145
+
1146
+    /**
1147
+     * Adds a new indexes
1148
+     *
1149
+     * @param  string $tablename
1150
+     * @param  array  $indexes   indexes to add
1151
+     * @param  bool   $execute   true if we want to execute the returned sql statement
1152
+     * @return string SQL statement
1153
+     */
1154
+    public function addIndexes($tablename, $indexes, $execute = true)
1155
+    {
1156
+        $alters = $this->getConstraintSql($indexes, $tablename);
1157
+        if ($execute) {
1158
+            foreach($alters as $sql) {
1159
+                $this->query($sql, true, "Error adding index: ");
1160
+            }
1161
+        }
1162
+        if(!empty($alters)) {
1163
+            $sql = join(";\n", $alters).";\n";
1164
+        } else {
1165
+            $sql = '';
1166
+        }
1167
+        return $sql;
1168
+    }
1169
+
1170
+    /**
1171
+     * Drops indexes
1172
+     *
1173
+     * @param  string $tablename
1174
+     * @param  array  $indexes   indexes to drop
1175
+     * @param  bool   $execute   true if we want to execute the returned sql statement
1176
+     * @return string SQL statement
1177
+     */
1178
+    public function dropIndexes($tablename, $indexes, $execute = true)
1179
+    {
1180
+        $sqls = array();
1181
+        foreach ($indexes as $index) {
1182
+            $name =$index['name'];
1183
+            $sqls[$name] = $this->add_drop_constraint($tablename,$index,true);
1184
+        }
1185
+        if (!empty($sqls) && $execute) {
1186
+            foreach($sqls as $name => $sql) {
1187
+                unset(self::$index_descriptions[$tablename][$name]);
1188
+                $this->query($sql);
1189
+            }
1190
+        }
1191
+        if(!empty($sqls)) {
1192
+            return join(";\n",$sqls).";";
1193
+        } else {
1194
+            return '';
1195
+        }
1196
+    }
1197
+
1198
+    /**
1199
+     * Modifies indexes
1200
+     *
1201
+     * @param  string $tablename
1202
+     * @param  array  $indexes   indexes to modify
1203
+     * @param  bool   $execute   true if we want to execute the returned sql statement
1204
+     * @return string SQL statement
1205
+     */
1206
+    public function modifyIndexes($tablename, $indexes, $execute = true)
1207
+    {
1208
+        return $this->dropIndexes($tablename, $indexes, $execute)."\n".
1209
+            $this->addIndexes($tablename, $indexes, $execute);
1210
+    }
1211
+
1212
+    /**
1213
+     * Adds a column to table identified by field def.
1214
+     *
1215
+     * @param string $tablename
1216
+     * @param array  $fieldDefs
1217 1217
      * @return bool query result
1218 1218
      */
1219
-	public function addColumn($tablename, $fieldDefs)
1220
-	{
1221
-		$sql = $this->addColumnSQL($tablename, $fieldDefs);
1222
-		if ($this->isFieldArray($fieldDefs)){
1223
-			$columns = array();
1224
-			foreach ($fieldDefs as $fieldDef)
1225
-				$columns[] = $fieldDef['name'];
1226
-			$columns = implode(",", $columns);
1227
-		}
1228
-		else {
1229
-			$columns = $fieldDefs['name'];
1230
-		}
1231
-		$msg = "Error adding column(s) $columns on table: $tablename:";
1232
-		return $this->query($sql,true,$msg);
1233
-	}
1234
-
1235
-	/**
1236
-	 * Alters old column identified by oldFieldDef to new fieldDef.
1237
-	 *
1238
-	 * @param string $tablename
1239
-	 * @param array  $newFieldDef
1240
-	 * @param bool   $ignoreRequired optional, true if we are ignoring this being a required field
1219
+    public function addColumn($tablename, $fieldDefs)
1220
+    {
1221
+        $sql = $this->addColumnSQL($tablename, $fieldDefs);
1222
+        if ($this->isFieldArray($fieldDefs)){
1223
+            $columns = array();
1224
+            foreach ($fieldDefs as $fieldDef)
1225
+                $columns[] = $fieldDef['name'];
1226
+            $columns = implode(",", $columns);
1227
+        }
1228
+        else {
1229
+            $columns = $fieldDefs['name'];
1230
+        }
1231
+        $msg = "Error adding column(s) $columns on table: $tablename:";
1232
+        return $this->query($sql,true,$msg);
1233
+    }
1234
+
1235
+    /**
1236
+     * Alters old column identified by oldFieldDef to new fieldDef.
1237
+     *
1238
+     * @param string $tablename
1239
+     * @param array  $newFieldDef
1240
+     * @param bool   $ignoreRequired optional, true if we are ignoring this being a required field
1241 1241
      * @return bool query result
1242 1242
      */
1243
-	public function alterColumn($tablename, $newFieldDef, $ignoreRequired = false)
1244
-	{
1245
-		$sql = $this->alterColumnSQL($tablename, $newFieldDef,$ignoreRequired);
1246
-		if ($this->isFieldArray($newFieldDef)){
1247
-			$columns = array();
1248
-			foreach ($newFieldDef as $fieldDef) {
1249
-				$columns[] = $fieldDef['name'];
1250
-			}
1251
-			$columns = implode(",", $columns);
1252
-		}
1253
-		else {
1254
-			$columns = $newFieldDef['name'];
1255
-		}
1256
-
1257
-		$msg = "Error altering column(s) $columns on table: $tablename:";
1258
-		$res = $this->query($sql,true,$msg);
1259
-		if($res) {
1260
-			$this->getTableDescription($tablename, true); // reload table description after altering
1261
-		}
1262
-		return $res;
1263
-	}
1264
-
1265
-	/**
1266
-	 * Drops the table associated with a bean
1267
-	 *
1268
-	 * @param SugarBean $bean SugarBean instance
1243
+    public function alterColumn($tablename, $newFieldDef, $ignoreRequired = false)
1244
+    {
1245
+        $sql = $this->alterColumnSQL($tablename, $newFieldDef,$ignoreRequired);
1246
+        if ($this->isFieldArray($newFieldDef)){
1247
+            $columns = array();
1248
+            foreach ($newFieldDef as $fieldDef) {
1249
+                $columns[] = $fieldDef['name'];
1250
+            }
1251
+            $columns = implode(",", $columns);
1252
+        }
1253
+        else {
1254
+            $columns = $newFieldDef['name'];
1255
+        }
1256
+
1257
+        $msg = "Error altering column(s) $columns on table: $tablename:";
1258
+        $res = $this->query($sql,true,$msg);
1259
+        if($res) {
1260
+            $this->getTableDescription($tablename, true); // reload table description after altering
1261
+        }
1262
+        return $res;
1263
+    }
1264
+
1265
+    /**
1266
+     * Drops the table associated with a bean
1267
+     *
1268
+     * @param SugarBean $bean SugarBean instance
1269 1269
      * @return bool query result
1270
-	 */
1271
-	public function dropTable(SugarBean $bean)
1272
-	{
1273
-		return $this->dropTableName($bean->getTableName());
1274
-	}
1275
-
1276
-	/**
1277
-	 * Drops the table by name
1278
-	 *
1279
-	 * @param string $name Table name
1270
+     */
1271
+    public function dropTable(SugarBean $bean)
1272
+    {
1273
+        return $this->dropTableName($bean->getTableName());
1274
+    }
1275
+
1276
+    /**
1277
+     * Drops the table by name
1278
+     *
1279
+     * @param string $name Table name
1280 1280
      * @return bool query result
1281
-	 */
1282
-	public function dropTableName($name)
1283
-	{
1284
-		$sql = $this->dropTableNameSQL($name);
1285
-		return $this->query($sql,true,"Error dropping table $name:");
1286
-	}
1281
+     */
1282
+    public function dropTableName($name)
1283
+    {
1284
+        $sql = $this->dropTableNameSQL($name);
1285
+        return $this->query($sql,true,"Error dropping table $name:");
1286
+    }
1287 1287
 
1288 1288
     /**
1289 1289
      * Deletes a column identified by fieldDef.
@@ -1292,13 +1292,13 @@  discard block
 block discarded – undo
1292 1292
      * @param array  $fieldDefs Vardef definition of the field
1293 1293
      * @return bool query result
1294 1294
      */
1295
-	public function deleteColumn(SugarBean $bean, $fieldDefs)
1296
-	{
1297
-		$tablename = $bean->getTableName();
1298
-		$sql = $this->dropColumnSQL($tablename, $fieldDefs);
1299
-		$msg = "Error deleting column(s) on table: $tablename:";
1300
-		return $this->query($sql,true,$msg);
1301
-	}
1295
+    public function deleteColumn(SugarBean $bean, $fieldDefs)
1296
+    {
1297
+        $tablename = $bean->getTableName();
1298
+        $sql = $this->dropColumnSQL($tablename, $fieldDefs);
1299
+        $msg = "Error deleting column(s) on table: $tablename:";
1300
+        return $this->query($sql,true,$msg);
1301
+    }
1302 1302
 
1303 1303
     /**
1304 1304
      * Generate a set of Insert statements based on the bean given
@@ -1313,228 +1313,228 @@  discard block
 block discarded – undo
1313 1313
      * @param bool $is_related_query
1314 1314
      * @return string SQL insert statement
1315 1315
      */
1316
-	public function generateInsertSQL(SugarBean $bean, $select_query, $start, $count = -1, $table, $is_related_query = false)
1317
-	{
1318
-		$this->log->info('call to DBManager::generateInsertSQL() is deprecated');
1319
-		global $sugar_config;
1320
-
1321
-		$rows_found = 0;
1322
-		$count_query = $bean->create_list_count_query($select_query);
1323
-		if(!empty($count_query))
1324
-		{
1325
-			// We have a count query.  Run it and get the results.
1326
-			$result = $this->query($count_query, true, "Error running count query for $this->object_name List: ");
1327
-			$assoc = $this->fetchByAssoc($result);
1328
-			if(!empty($assoc['c']))
1329
-			{
1330
-				$rows_found = $assoc['c'];
1331
-			}
1332
-		}
1333
-		if($count == -1){
1334
-			$count 	= $sugar_config['list_max_entries_per_page'];
1335
-		}
1336
-		$next_offset = $start + $count;
1337
-
1338
-		$result = $this->limitQuery($select_query, $start, $count);
1339
-		// get basic insert
1340
-		$sql = "INSERT INTO ".$table;
1341
-		$custom_sql = "INSERT INTO ".$table."_cstm";
1342
-
1343
-		// get field definitions
1344
-		$fields = $bean->getFieldDefinitions();
1345
-		$custom_fields = array();
1346
-
1347
-		if($bean->hasCustomFields()){
1348
-			foreach ($fields as $fieldDef){
1349
-				if($fieldDef['source'] == 'custom_fields'){
1350
-					$custom_fields[$fieldDef['name']] = $fieldDef['name'];
1351
-				}
1352
-			}
1353
-			if(!empty($custom_fields)){
1354
-				$custom_fields['id_c'] = 'id_c';
1355
-				$id_field = array('name' => 'id_c', 'custom_type' => 'id',);
1356
-				$fields[] = $id_field;
1357
-			}
1358
-		}
1359
-
1360
-		// get column names and values
1361
-		$row_array = array();
1362
-		$columns = array();
1363
-		$cstm_row_array = array();
1364
-		$cstm_columns = array();
1365
-		$built_columns = false;
1366
-		while(($row = $this->fetchByAssoc($result)) != null)
1367
-		{
1368
-			$values = array();
1369
-			$cstm_values = array();
1370
-			if(!$is_related_query){
1371
-				foreach ($fields as $fieldDef)
1372
-				{
1373
-					if(isset($fieldDef['source']) && $fieldDef['source'] != 'db' && $fieldDef['source'] != 'custom_fields') continue;
1374
-					$val = $row[$fieldDef['name']];
1375
-
1376
-					//handle auto increment values here only need to do this on insert not create
1377
-					if ($fieldDef['name'] == 'deleted'){
1378
-							$values['deleted'] = $val;
1379
-							if(!$built_columns){
1380
-							$columns[] = 'deleted';
1381
-						}
1382
-					}
1383
-					else
1384
-					{
1385
-						$type = $fieldDef['type'];
1386
-						if(!empty($fieldDef['custom_type'])){
1387
-							$type = $fieldDef['custom_type'];
1388
-						}
1389
-						// need to do some thing about types of values
1390
-						if($this->dbType == 'mysql' && $val == '' && ($type == 'datetime' ||  $type == 'date' || $type == 'int' || $type == 'currency' || $type == 'decimal')){
1391
-							if(!empty($custom_fields[$fieldDef['name']]))
1392
-								$cstm_values[$fieldDef['name']] = 'null';
1393
-							else
1394
-								$values[$fieldDef['name']] = 'null';
1395
-						}else{
1396
-							if(isset($type) && $type=='int') {
1397
-								if(!empty($custom_fields[$fieldDef['name']]))
1398
-									$cstm_values[$fieldDef['name']] = $GLOBALS['db']->quote(from_html($val));
1399
-								else
1400
-									$values[$fieldDef['name']] = $GLOBALS['db']->quote(from_html($val));
1401
-							} else {
1402
-								if(!empty($custom_fields[$fieldDef['name']]))
1403
-									$cstm_values[$fieldDef['name']] = "'".$GLOBALS['db']->quote(from_html($val))."'";
1404
-								else
1405
-									$values[$fieldDef['name']] = "'".$GLOBALS['db']->quote(from_html($val))."'";
1406
-							}
1407
-						}
1408
-						if(!$built_columns){
1409
-							if(!empty($custom_fields[$fieldDef['name']]))
1410
-								$cstm_columns[] = $fieldDef['name'];
1411
-							else
1412
-								$columns[] = $fieldDef['name'];
1413
-						}
1414
-					}
1415
-
1416
-				}
1417
-			} else {
1418
-			foreach ($row as $key=>$val)
1419
-			{
1420
-					if($key != 'orc_row'){
1421
-						$values[$key] = "'$val'";
1422
-						if(!$built_columns){
1423
-							$columns[] = $key;
1424
-						}
1425
-					}
1426
-			}
1427
-			}
1428
-			$built_columns = true;
1429
-			if(!empty($values)){
1430
-				$row_array[] = $values;
1431
-			}
1432
-			if(!empty($cstm_values) && !empty($cstm_values['id_c']) && (strlen($cstm_values['id_c']) > 7)){
1433
-				$cstm_row_array[] = $cstm_values;
1434
-			}
1435
-		}
1436
-
1437
-		//if (sizeof ($values) == 0) return ""; // no columns set
1438
-
1439
-		// get the entire sql
1440
-		$sql .= "(".implode(",", $columns).") ";
1441
-		$sql .= "VALUES";
1442
-		for($i = 0; $i < count($row_array); $i++){
1443
-			$sql .= " (".implode(",", $row_array[$i]).")";
1444
-			if($i < (count($row_array) - 1)){
1445
-				$sql .= ", ";
1446
-			}
1447
-		}
1448
-		//custom
1449
-		// get the entire sql
1450
-		$custom_sql .= "(".implode(",", $cstm_columns).") ";
1451
-		$custom_sql .= "VALUES";
1452
-
1453
-		for($i = 0; $i < count($cstm_row_array); $i++){
1454
-			$custom_sql .= " (".implode(",", $cstm_row_array[$i]).")";
1455
-			if($i < (count($cstm_row_array) - 1)){
1456
-				$custom_sql .= ", ";
1457
-			}
1458
-		}
1459
-		return array('data' => $sql, 'cstm_sql' => $custom_sql, /*'result_count' => $row_count, */ 'total_count' => $rows_found, 'next_offset' => $next_offset);
1460
-	}
1461
-
1462
-	/**
1463
-	 * @deprecated
1464
-	 * Disconnects all instances
1465
-	 */
1466
-	public function disconnectAll()
1467
-	{
1468
-		DBManagerFactory::disconnectAll();
1469
-	}
1470
-
1471
-	/**
1472
-	 * This function sets the query threshold limit
1473
-	 *
1474
-	 * @param int $limit value of query threshold limit
1475
-	 */
1476
-	public static function setQueryLimit($limit)
1477
-	{
1478
-		//reset the queryCount
1479
-		self::$queryCount = 0;
1480
-		self::$queryLimit = $limit;
1481
-	}
1482
-
1483
-	/**
1484
-	 * Returns the static queryCount value
1485
-	 *
1486
-	 * @return int value of the queryCount static variable
1487
-	 */
1488
-	public static function getQueryCount()
1489
-	{
1490
-		return self::$queryCount;
1491
-	}
1492
-
1493
-
1494
-	/**
1495
-	 * Resets the queryCount value to 0
1496
-	 *
1497
-	 */
1498
-	public static function resetQueryCount()
1499
-	{
1500
-		self::$queryCount = 0;
1501
-	}
1502
-
1503
-	/**
1504
-	 * This function increments the global $sql_queries variable
1505
-	 */
1506
-	public function countQuery()
1507
-	{
1508
-		if (self::$queryLimit != 0 && ++self::$queryCount > self::$queryLimit
1509
-			&&(empty($GLOBALS['current_user']) || !is_admin($GLOBALS['current_user']))) {
1316
+    public function generateInsertSQL(SugarBean $bean, $select_query, $start, $count = -1, $table, $is_related_query = false)
1317
+    {
1318
+        $this->log->info('call to DBManager::generateInsertSQL() is deprecated');
1319
+        global $sugar_config;
1320
+
1321
+        $rows_found = 0;
1322
+        $count_query = $bean->create_list_count_query($select_query);
1323
+        if(!empty($count_query))
1324
+        {
1325
+            // We have a count query.  Run it and get the results.
1326
+            $result = $this->query($count_query, true, "Error running count query for $this->object_name List: ");
1327
+            $assoc = $this->fetchByAssoc($result);
1328
+            if(!empty($assoc['c']))
1329
+            {
1330
+                $rows_found = $assoc['c'];
1331
+            }
1332
+        }
1333
+        if($count == -1){
1334
+            $count 	= $sugar_config['list_max_entries_per_page'];
1335
+        }
1336
+        $next_offset = $start + $count;
1337
+
1338
+        $result = $this->limitQuery($select_query, $start, $count);
1339
+        // get basic insert
1340
+        $sql = "INSERT INTO ".$table;
1341
+        $custom_sql = "INSERT INTO ".$table."_cstm";
1342
+
1343
+        // get field definitions
1344
+        $fields = $bean->getFieldDefinitions();
1345
+        $custom_fields = array();
1346
+
1347
+        if($bean->hasCustomFields()){
1348
+            foreach ($fields as $fieldDef){
1349
+                if($fieldDef['source'] == 'custom_fields'){
1350
+                    $custom_fields[$fieldDef['name']] = $fieldDef['name'];
1351
+                }
1352
+            }
1353
+            if(!empty($custom_fields)){
1354
+                $custom_fields['id_c'] = 'id_c';
1355
+                $id_field = array('name' => 'id_c', 'custom_type' => 'id',);
1356
+                $fields[] = $id_field;
1357
+            }
1358
+        }
1359
+
1360
+        // get column names and values
1361
+        $row_array = array();
1362
+        $columns = array();
1363
+        $cstm_row_array = array();
1364
+        $cstm_columns = array();
1365
+        $built_columns = false;
1366
+        while(($row = $this->fetchByAssoc($result)) != null)
1367
+        {
1368
+            $values = array();
1369
+            $cstm_values = array();
1370
+            if(!$is_related_query){
1371
+                foreach ($fields as $fieldDef)
1372
+                {
1373
+                    if(isset($fieldDef['source']) && $fieldDef['source'] != 'db' && $fieldDef['source'] != 'custom_fields') continue;
1374
+                    $val = $row[$fieldDef['name']];
1375
+
1376
+                    //handle auto increment values here only need to do this on insert not create
1377
+                    if ($fieldDef['name'] == 'deleted'){
1378
+                            $values['deleted'] = $val;
1379
+                            if(!$built_columns){
1380
+                            $columns[] = 'deleted';
1381
+                        }
1382
+                    }
1383
+                    else
1384
+                    {
1385
+                        $type = $fieldDef['type'];
1386
+                        if(!empty($fieldDef['custom_type'])){
1387
+                            $type = $fieldDef['custom_type'];
1388
+                        }
1389
+                        // need to do some thing about types of values
1390
+                        if($this->dbType == 'mysql' && $val == '' && ($type == 'datetime' ||  $type == 'date' || $type == 'int' || $type == 'currency' || $type == 'decimal')){
1391
+                            if(!empty($custom_fields[$fieldDef['name']]))
1392
+                                $cstm_values[$fieldDef['name']] = 'null';
1393
+                            else
1394
+                                $values[$fieldDef['name']] = 'null';
1395
+                        }else{
1396
+                            if(isset($type) && $type=='int') {
1397
+                                if(!empty($custom_fields[$fieldDef['name']]))
1398
+                                    $cstm_values[$fieldDef['name']] = $GLOBALS['db']->quote(from_html($val));
1399
+                                else
1400
+                                    $values[$fieldDef['name']] = $GLOBALS['db']->quote(from_html($val));
1401
+                            } else {
1402
+                                if(!empty($custom_fields[$fieldDef['name']]))
1403
+                                    $cstm_values[$fieldDef['name']] = "'".$GLOBALS['db']->quote(from_html($val))."'";
1404
+                                else
1405
+                                    $values[$fieldDef['name']] = "'".$GLOBALS['db']->quote(from_html($val))."'";
1406
+                            }
1407
+                        }
1408
+                        if(!$built_columns){
1409
+                            if(!empty($custom_fields[$fieldDef['name']]))
1410
+                                $cstm_columns[] = $fieldDef['name'];
1411
+                            else
1412
+                                $columns[] = $fieldDef['name'];
1413
+                        }
1414
+                    }
1415
+
1416
+                }
1417
+            } else {
1418
+            foreach ($row as $key=>$val)
1419
+            {
1420
+                    if($key != 'orc_row'){
1421
+                        $values[$key] = "'$val'";
1422
+                        if(!$built_columns){
1423
+                            $columns[] = $key;
1424
+                        }
1425
+                    }
1426
+            }
1427
+            }
1428
+            $built_columns = true;
1429
+            if(!empty($values)){
1430
+                $row_array[] = $values;
1431
+            }
1432
+            if(!empty($cstm_values) && !empty($cstm_values['id_c']) && (strlen($cstm_values['id_c']) > 7)){
1433
+                $cstm_row_array[] = $cstm_values;
1434
+            }
1435
+        }
1436
+
1437
+        //if (sizeof ($values) == 0) return ""; // no columns set
1438
+
1439
+        // get the entire sql
1440
+        $sql .= "(".implode(",", $columns).") ";
1441
+        $sql .= "VALUES";
1442
+        for($i = 0; $i < count($row_array); $i++){
1443
+            $sql .= " (".implode(",", $row_array[$i]).")";
1444
+            if($i < (count($row_array) - 1)){
1445
+                $sql .= ", ";
1446
+            }
1447
+        }
1448
+        //custom
1449
+        // get the entire sql
1450
+        $custom_sql .= "(".implode(",", $cstm_columns).") ";
1451
+        $custom_sql .= "VALUES";
1452
+
1453
+        for($i = 0; $i < count($cstm_row_array); $i++){
1454
+            $custom_sql .= " (".implode(",", $cstm_row_array[$i]).")";
1455
+            if($i < (count($cstm_row_array) - 1)){
1456
+                $custom_sql .= ", ";
1457
+            }
1458
+        }
1459
+        return array('data' => $sql, 'cstm_sql' => $custom_sql, /*'result_count' => $row_count, */ 'total_count' => $rows_found, 'next_offset' => $next_offset);
1460
+    }
1461
+
1462
+    /**
1463
+     * @deprecated
1464
+     * Disconnects all instances
1465
+     */
1466
+    public function disconnectAll()
1467
+    {
1468
+        DBManagerFactory::disconnectAll();
1469
+    }
1470
+
1471
+    /**
1472
+     * This function sets the query threshold limit
1473
+     *
1474
+     * @param int $limit value of query threshold limit
1475
+     */
1476
+    public static function setQueryLimit($limit)
1477
+    {
1478
+        //reset the queryCount
1479
+        self::$queryCount = 0;
1480
+        self::$queryLimit = $limit;
1481
+    }
1482
+
1483
+    /**
1484
+     * Returns the static queryCount value
1485
+     *
1486
+     * @return int value of the queryCount static variable
1487
+     */
1488
+    public static function getQueryCount()
1489
+    {
1490
+        return self::$queryCount;
1491
+    }
1492
+
1493
+
1494
+    /**
1495
+     * Resets the queryCount value to 0
1496
+     *
1497
+     */
1498
+    public static function resetQueryCount()
1499
+    {
1500
+        self::$queryCount = 0;
1501
+    }
1502
+
1503
+    /**
1504
+     * This function increments the global $sql_queries variable
1505
+     */
1506
+    public function countQuery()
1507
+    {
1508
+        if (self::$queryLimit != 0 && ++self::$queryCount > self::$queryLimit
1509
+            &&(empty($GLOBALS['current_user']) || !is_admin($GLOBALS['current_user']))) {
1510 1510
             require_once('include/resource/ResourceManager.php');
1511 1511
             $resourceManager = ResourceManager::getInstance();
1512 1512
             $resourceManager->notifyObservers('ERR_QUERY_LIMIT');
1513
-		}
1514
-	}
1513
+        }
1514
+    }
1515
+
1516
+    /**
1517
+     * Pre-process string for quoting
1518
+     * @internal
1519
+     * @param string $string
1520
+     * @return string
1521
+     */
1522
+    protected function quoteInternal($string)
1523
+    {
1524
+        return from_html($string);
1525
+    }
1515 1526
 
1516
-	/**
1517
-	 * Pre-process string for quoting
1518
-	 * @internal
1519
-	 * @param string $string
1527
+    /**
1528
+     * Return string properly quoted with ''
1529
+     * @param string $string
1520 1530
      * @return string
1521 1531
      */
1522
-	protected function quoteInternal($string)
1523
-	{
1524
-		return from_html($string);
1525
-	}
1526
-
1527
-	/**
1528
-	 * Return string properly quoted with ''
1529
-	 * @param string $string
1530
-	 * @return string
1531
-	 */
1532
-	public function quoted($string)
1533
-	{
1534
-		return "'".$this->quote($string)."'";
1535
-	}
1536
-
1537
-	/**
1532
+    public function quoted($string)
1533
+    {
1534
+        return "'".$this->quote($string)."'";
1535
+    }
1536
+
1537
+    /**
1538 1538
      * Quote value according to type
1539 1539
      * Numerics aren't quoted
1540 1540
      * Dates are converted and quoted
@@ -1544,13 +1544,13 @@  discard block
 block discarded – undo
1544 1544
      * @return string Quoted value
1545 1545
      */
1546 1546
     public function quoteType($type, $value)
1547
-	{
1548
-	    if($type == 'date') {
1549
-	        return $this->convert($this->quoted($value), "date");
1550
-	    }
1551
-	    if($type == 'time') {
1552
-	        return $this->convert($this->quoted($value), "time");
1553
-	    }
1547
+    {
1548
+        if($type == 'date') {
1549
+            return $this->convert($this->quoted($value), "date");
1550
+        }
1551
+        if($type == 'time') {
1552
+            return $this->convert($this->quoted($value), "time");
1553
+        }
1554 1554
         if(isset($this->type_class[$type]) &&  $this->type_class[$type] == "date") {
1555 1555
             return $this->convert($this->quoted($value), "datetime");
1556 1556
         }
@@ -1559,7 +1559,7 @@  discard block
 block discarded – undo
1559 1559
         }
1560 1560
 
1561 1561
         return $this->quoted($value);
1562
-	}
1562
+    }
1563 1563
 
1564 1564
     /**
1565 1565
      * Quote the strings of the passed in array
@@ -1569,177 +1569,177 @@  discard block
 block discarded – undo
1569 1569
      * @param array $array
1570 1570
      * @return array Quoted strings
1571 1571
      */
1572
-	public function arrayQuote(array &$array)
1573
-	{
1574
-		foreach($array as &$val) {
1575
-			$val = $this->quote($val);
1576
-		}
1577
-		return $array;
1578
-	}
1572
+    public function arrayQuote(array &$array)
1573
+    {
1574
+        foreach($array as &$val) {
1575
+            $val = $this->quote($val);
1576
+        }
1577
+        return $array;
1578
+    }
1579 1579
 
1580 1580
     /**
1581 1581
      * Frees out previous results
1582 1582
      *
1583 1583
      * @param resource|bool $result optional, pass if you want to free a single result instead of all results
1584 1584
      */
1585
-	protected function freeResult($result = false)
1586
-	{
1587
-		if($result) {
1588
-			$this->freeDbResult($result);
1589
-		}
1590
-		if($this->lastResult) {
1591
-			$this->freeDbResult($this->lastResult);
1592
-			$this->lastResult = null;
1593
-		}
1594
-	}
1595
-
1596
-	/**
1597
-	 * @abstract
1598
-	 * Check if query has LIMIT clause
1599
-	 * Relevant for now only for Mysql
1600
-	 * @param string $sql
1601
-	 * @return bool
1602
-	 */
1603
-	protected function hasLimit($sql)
1604
-	{
1605
-	    return false;
1606
-	}
1607
-
1608
-	/**
1609
-	 * Runs a query and returns a single row containing single value
1610
-	 *
1611
-	 * @param  string   $sql        SQL Statement to execute
1612
-	 * @param  bool     $dieOnError True if we want to call die if the query returns errors
1613
-	 * @param  string   $msg        Message to log if error occurs
1614
-	 * @return array    single value from the query
1615
-	 */
1616
-	public function getOne($sql, $dieOnError = false, $msg = '')
1617
-	{
1618
-		$this->log->info("Get One: |$sql|");
1619
-		if(!$this->hasLimit($sql)) {
1620
-		    $queryresult = $this->limitQuery($sql, 0, 1, $dieOnError, $msg);
1621
-		} else {
1622
-		    // support old code that passes LIMIT to sql
1623
-		    // works only for mysql, so do not rely on this
1624
-		    $queryresult = $this->query($sql, $dieOnError, $msg);
1625
-		}
1626
-		$this->checkError($msg.' Get One Failed:' . $sql, $dieOnError);
1627
-		if (!$queryresult) return false;
1628
-		$row = $this->fetchByAssoc($queryresult);
1629
-		if(!empty($row)) {
1630
-			return array_shift($row);
1631
-		}
1632
-		return false;
1633
-	}
1634
-
1635
-	/**
1636
-	 * Runs a query and returns a single row
1637
-	 *
1638
-	 * @param  string   $sql        SQL Statement to execute
1639
-	 * @param  bool     $dieOnError True if we want to call die if the query returns errors
1640
-	 * @param  string   $msg        Message to log if error occurs
1641
-	 * @param  bool     $suppress   Message to log if error occurs
1642
-	 * @return array    single row from the query
1643
-	 */
1644
-	public function fetchOne($sql, $dieOnError = false, $msg = '', $suppress = false)
1645
-	{
1646
-		$this->log->info("Fetch One: |$sql|");
1647
-		$this->checkConnection();
1648
-		$queryresult = $this->query($sql, $dieOnError, $msg);
1649
-		$this->checkError($msg.' Fetch One Failed:' . $sql, $dieOnError);
1650
-
1651
-		if (!$queryresult) return false;
1652
-
1653
-		$row = $this->fetchByAssoc($queryresult);
1654
-		if ( !$row ) return false;
1655
-
1656
-		$this->freeResult($queryresult);
1657
-		return $row;
1658
-	}
1585
+    protected function freeResult($result = false)
1586
+    {
1587
+        if($result) {
1588
+            $this->freeDbResult($result);
1589
+        }
1590
+        if($this->lastResult) {
1591
+            $this->freeDbResult($this->lastResult);
1592
+            $this->lastResult = null;
1593
+        }
1594
+    }
1659 1595
 
1660 1596
     /**
1661
-     * Returns the number of rows affected by the last query
1662 1597
      * @abstract
1663
-	 * See also affected_rows capability, will return 0 unless the DB supports it
1664
-     * @param resource $result query result resource
1665
-     * @return int
1598
+     * Check if query has LIMIT clause
1599
+     * Relevant for now only for Mysql
1600
+     * @param string $sql
1601
+     * @return bool
1666 1602
      */
1667
-	public function getAffectedRowCount($result)
1668
-	{
1669
-		return 0;
1670
-	}
1671
-
1672
-	/**
1673
-	 * Returns the number of rows returned by the result
1674
-	 *
1675
-	 * This function can't be reliably implemented on most DB, do not use it.
1676
-	 * @abstract
1677
-	 * @deprecated
1678
-	 * @param  resource $result
1679
-	 * @return int
1680
-	 */
1681
-	public function getRowCount($result)
1682
-	{
1683
-	    return 0;
1684
-	}
1685
-
1686
-	/**
1687
-     * Get table description
1688
-     * @param string $tablename
1603
+    protected function hasLimit($sql)
1604
+    {
1605
+        return false;
1606
+    }
1607
+
1608
+    /**
1609
+     * Runs a query and returns a single row containing single value
1610
+     *
1611
+     * @param  string   $sql        SQL Statement to execute
1612
+     * @param  bool     $dieOnError True if we want to call die if the query returns errors
1613
+     * @param  string   $msg        Message to log if error occurs
1614
+     * @return array    single value from the query
1615
+     */
1616
+    public function getOne($sql, $dieOnError = false, $msg = '')
1617
+    {
1618
+        $this->log->info("Get One: |$sql|");
1619
+        if(!$this->hasLimit($sql)) {
1620
+            $queryresult = $this->limitQuery($sql, 0, 1, $dieOnError, $msg);
1621
+        } else {
1622
+            // support old code that passes LIMIT to sql
1623
+            // works only for mysql, so do not rely on this
1624
+            $queryresult = $this->query($sql, $dieOnError, $msg);
1625
+        }
1626
+        $this->checkError($msg.' Get One Failed:' . $sql, $dieOnError);
1627
+        if (!$queryresult) return false;
1628
+        $row = $this->fetchByAssoc($queryresult);
1629
+        if(!empty($row)) {
1630
+            return array_shift($row);
1631
+        }
1632
+        return false;
1633
+    }
1634
+
1635
+    /**
1636
+     * Runs a query and returns a single row
1637
+     *
1638
+     * @param  string   $sql        SQL Statement to execute
1639
+     * @param  bool     $dieOnError True if we want to call die if the query returns errors
1640
+     * @param  string   $msg        Message to log if error occurs
1641
+     * @param  bool     $suppress   Message to log if error occurs
1642
+     * @return array    single row from the query
1643
+     */
1644
+    public function fetchOne($sql, $dieOnError = false, $msg = '', $suppress = false)
1645
+    {
1646
+        $this->log->info("Fetch One: |$sql|");
1647
+        $this->checkConnection();
1648
+        $queryresult = $this->query($sql, $dieOnError, $msg);
1649
+        $this->checkError($msg.' Fetch One Failed:' . $sql, $dieOnError);
1650
+
1651
+        if (!$queryresult) return false;
1652
+
1653
+        $row = $this->fetchByAssoc($queryresult);
1654
+        if ( !$row ) return false;
1655
+
1656
+        $this->freeResult($queryresult);
1657
+        return $row;
1658
+    }
1659
+
1660
+    /**
1661
+     * Returns the number of rows affected by the last query
1662
+     * @abstract
1663
+     * See also affected_rows capability, will return 0 unless the DB supports it
1664
+     * @param resource $result query result resource
1665
+     * @return int
1666
+     */
1667
+    public function getAffectedRowCount($result)
1668
+    {
1669
+        return 0;
1670
+    }
1671
+
1672
+    /**
1673
+     * Returns the number of rows returned by the result
1674
+     *
1675
+     * This function can't be reliably implemented on most DB, do not use it.
1676
+     * @abstract
1677
+     * @deprecated
1678
+     * @param  resource $result
1679
+     * @return int
1680
+     */
1681
+    public function getRowCount($result)
1682
+    {
1683
+        return 0;
1684
+    }
1685
+
1686
+    /**
1687
+     * Get table description
1688
+     * @param string $tablename
1689 1689
      * @param bool $reload true means load from DB, false allows using cache
1690 1690
      * @return array Vardef-format table description
1691 1691
      *
1692 1692
      */
1693
-	public function getTableDescription($tablename, $reload = false)
1694
-	{
1695
-		if($reload || empty(self::$table_descriptions[$tablename])) {
1696
-			self::$table_descriptions[$tablename] = $this->get_columns($tablename);
1697
-		}
1698
-		return self::$table_descriptions[$tablename];
1699
-	}
1700
-
1701
-	/**
1702
-	 * Returns the field description for a given field in table
1703
-	 *
1704
-	 * @param  string $name
1705
-	 * @param  string $tablename
1706
-	 * @return array
1707
-	 */
1708
-	protected function describeField($name, $tablename)
1709
-	{
1710
-		$table = $this->getTableDescription($tablename);
1711
-		if(!empty($table) && isset($table[$name]))
1712
-			return 	$table[$name];
1713
-
1714
-		$table = $this->getTableDescription($tablename, true);
1715
-
1716
-		if(isset($table[$name]))
1717
-		return $table[$name];
1718
-
1719
-		return array();
1720
-	}
1721
-
1722
-	/**
1723
-	 * Returns the index description for a given index in table
1724
-	 *
1725
-	 * @param  string $name
1726
-	 * @param  string $tablename
1727
-	 * @return array
1728
-	 */
1729
-	protected function describeIndex($name, $tablename)
1730
-	{
1731
-		if(isset(self::$index_descriptions[$tablename]) && isset(self::$index_descriptions[$tablename]) && isset(self::$index_descriptions[$tablename][$name])){
1732
-			return 	self::$index_descriptions[$tablename][$name];
1733
-		}
1734
-
1735
-		self::$index_descriptions[$tablename] = $this->get_indices($tablename);
1736
-
1737
-		if(isset(self::$index_descriptions[$tablename][$name])){
1738
-			return 	self::$index_descriptions[$tablename][$name];
1739
-		}
1740
-
1741
-		return array();
1742
-	}
1693
+    public function getTableDescription($tablename, $reload = false)
1694
+    {
1695
+        if($reload || empty(self::$table_descriptions[$tablename])) {
1696
+            self::$table_descriptions[$tablename] = $this->get_columns($tablename);
1697
+        }
1698
+        return self::$table_descriptions[$tablename];
1699
+    }
1700
+
1701
+    /**
1702
+     * Returns the field description for a given field in table
1703
+     *
1704
+     * @param  string $name
1705
+     * @param  string $tablename
1706
+     * @return array
1707
+     */
1708
+    protected function describeField($name, $tablename)
1709
+    {
1710
+        $table = $this->getTableDescription($tablename);
1711
+        if(!empty($table) && isset($table[$name]))
1712
+            return 	$table[$name];
1713
+
1714
+        $table = $this->getTableDescription($tablename, true);
1715
+
1716
+        if(isset($table[$name]))
1717
+        return $table[$name];
1718
+
1719
+        return array();
1720
+    }
1721
+
1722
+    /**
1723
+     * Returns the index description for a given index in table
1724
+     *
1725
+     * @param  string $name
1726
+     * @param  string $tablename
1727
+     * @return array
1728
+     */
1729
+    protected function describeIndex($name, $tablename)
1730
+    {
1731
+        if(isset(self::$index_descriptions[$tablename]) && isset(self::$index_descriptions[$tablename]) && isset(self::$index_descriptions[$tablename][$name])){
1732
+            return 	self::$index_descriptions[$tablename][$name];
1733
+        }
1734
+
1735
+        self::$index_descriptions[$tablename] = $this->get_indices($tablename);
1736
+
1737
+        if(isset(self::$index_descriptions[$tablename][$name])){
1738
+            return 	self::$index_descriptions[$tablename][$name];
1739
+        }
1740
+
1741
+        return array();
1742
+    }
1743 1743
 
1744 1744
     /**
1745 1745
      * Truncates a string to a given length
@@ -1749,14 +1749,14 @@  discard block
 block discarded – undo
1749 1749
      * @return string
1750 1750
      *
1751 1751
      */
1752
-	public function truncate($string, $len)
1753
-	{
1754
-		if ( is_numeric($len) && $len > 0)
1755
-		{
1756
-			$string = mb_substr($string,0,(int) $len, "UTF-8");
1757
-		}
1758
-		return $string;
1759
-	}
1752
+    public function truncate($string, $len)
1753
+    {
1754
+        if ( is_numeric($len) && $len > 0)
1755
+        {
1756
+            $string = mb_substr($string,0,(int) $len, "UTF-8");
1757
+        }
1758
+        return $string;
1759
+    }
1760 1760
 
1761 1761
     /**
1762 1762
      * Returns the database string needed for concatinating multiple database strings together
@@ -1766,121 +1766,121 @@  discard block
 block discarded – undo
1766 1766
      * @param string $space Separator between strings, default is single space
1767 1767
      * @return string
1768 1768
      */
1769
-	public function concat($table, array $fields, $space = ' ')
1770
-	{
1771
-		if(empty($fields)) return '';
1772
-		$elems = array();
1773
-		$space = $this->quoted($space);
1774
-		foreach ( $fields as $field ) {
1775
-			if(!empty($elems)) $elems[] = $space;
1776
-			$elems[] = $this->convert("$table.$field", 'IFNULL', array("''"));
1777
-		}
1778
-		$first = array_shift($elems);
1779
-		return "LTRIM(RTRIM(".$this->convert($first, 'CONCAT', $elems)."))";
1780
-	}
1781
-
1782
-	/**
1783
-	 * Given a sql stmt attempt to parse it into the sql and the tokens. Then return the index of this prepared statement
1784
-	 * Tokens can come in the following forms:
1785
-	 * ? - a scalar which will be quoted
1786
-	 * ! - a literal which will not be quoted
1787
-	 * & - binary data to read from a file
1788
-	 *
1789
-	 * @param  string	$sql        The sql to parse
1790
-	 * @return int index of the prepared statement to be used with execute
1791
-	 */
1792
-	public function prepareQuery($sql)
1793
-	{
1794
-		//parse out the tokens
1795
-		$tokens = preg_split('/((?<!\\\)[&?!])/', $sql, -1, PREG_SPLIT_DELIM_CAPTURE);
1796
-
1797
-		//maintain a count of the actual tokens for quick reference in execute
1798
-		$count = 0;
1799
-
1800
-		$sqlStr = '';
1801
-		foreach ($tokens as $key => $val) {
1802
-			switch ($val) {
1803
-				case '?' :
1804
-				case '!' :
1805
-				case '&' :
1806
-					$count++;
1807
-					$sqlStr .= '?';
1808
-					break;
1809
-
1810
-				default :
1811
-					//escape any special characters
1812
-					$tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
1813
-					$sqlStr .= $tokens[$key];
1814
-					break;
1815
-			} // switch
1816
-		} // foreach
1817
-
1818
-		$this->preparedTokens[] = array('tokens' => $tokens, 'tokenCount' => $count, 'sqlString' => $sqlStr);
1819
-		end($this->preparedTokens);
1820
-		return key($this->preparedTokens);
1821
-	}
1822
-
1823
-	/**
1824
-	 * Takes a prepared stmt index and the data to replace and creates the query and runs it.
1825
-	 *
1826
-	 * @param  int		$stmt       The index of the prepared statement from preparedTokens
1827
-	 * @param  array    $data 		The array of data to replace the tokens with.
1828
-	 * @return resource result set or false on error
1829
-	 */
1830
-	public function executePreparedQuery($stmt, $data = array())
1831
-	{
1832
-		if(!empty($this->preparedTokens[$stmt])){
1833
-			if(!is_array($data)){
1834
-				$data = array($data);
1835
-			}
1836
-
1837
-			$pTokens = $this->preparedTokens[$stmt];
1838
-
1839
-			//ensure that the number of data elements matches the number of replacement tokens
1840
-			//we found in prepare().
1841
-			if(count($data) != $pTokens['tokenCount']){
1842
-				//error the data count did not match the token count
1843
-				return false;
1844
-			}
1845
-
1846
-			$query = '';
1847
-			$dataIndex = 0;
1848
-			$tokens = $pTokens['tokens'];
1849
-			foreach ($tokens as $val) {
1850
-				switch ($val) {
1851
-					case '?':
1852
-						$query .= $this->quote($data[$dataIndex++]);
1853
-						break;
1854
-					case '&':
1855
-						$filename = $data[$dataIndex++];
1856
-						$query .= file_get_contents($filename);
1857
-						break;
1858
-					case '!':
1859
-						$query .= $data[$dataIndex++];
1860
-						break;
1861
-					default:
1862
-						$query .= $val;
1863
-						break;
1864
-				}//switch
1865
-			}//foreach
1866
-			return $this->query($query);
1867
-		}else{
1868
-			return false;
1869
-		}
1870
-	}
1871
-
1872
-	/**
1873
-	 * Run both prepare and execute without the client having to run both individually.
1874
-	 *
1875
-	 * @param  string	$sql        The sql to parse
1876
-	 * @param  array    $data 		The array of data to replace the tokens with.
1877
-	 * @return resource result set or false on error
1878
-	 */
1879
-	public function pQuery($sql, $data = array())
1880
-	{
1881
-		$stmt = $this->prepareQuery($sql);
1882
-		return $this->executePreparedQuery($stmt, $data);
1883
-	}
1769
+    public function concat($table, array $fields, $space = ' ')
1770
+    {
1771
+        if(empty($fields)) return '';
1772
+        $elems = array();
1773
+        $space = $this->quoted($space);
1774
+        foreach ( $fields as $field ) {
1775
+            if(!empty($elems)) $elems[] = $space;
1776
+            $elems[] = $this->convert("$table.$field", 'IFNULL', array("''"));
1777
+        }
1778
+        $first = array_shift($elems);
1779
+        return "LTRIM(RTRIM(".$this->convert($first, 'CONCAT', $elems)."))";
1780
+    }
1781
+
1782
+    /**
1783
+     * Given a sql stmt attempt to parse it into the sql and the tokens. Then return the index of this prepared statement
1784
+     * Tokens can come in the following forms:
1785
+     * ? - a scalar which will be quoted
1786
+     * ! - a literal which will not be quoted
1787
+     * & - binary data to read from a file
1788
+     *
1789
+     * @param  string	$sql        The sql to parse
1790
+     * @return int index of the prepared statement to be used with execute
1791
+     */
1792
+    public function prepareQuery($sql)
1793
+    {
1794
+        //parse out the tokens
1795
+        $tokens = preg_split('/((?<!\\\)[&?!])/', $sql, -1, PREG_SPLIT_DELIM_CAPTURE);
1796
+
1797
+        //maintain a count of the actual tokens for quick reference in execute
1798
+        $count = 0;
1799
+
1800
+        $sqlStr = '';
1801
+        foreach ($tokens as $key => $val) {
1802
+            switch ($val) {
1803
+                case '?' :
1804
+                case '!' :
1805
+                case '&' :
1806
+                    $count++;
1807
+                    $sqlStr .= '?';
1808
+                    break;
1809
+
1810
+                default :
1811
+                    //escape any special characters
1812
+                    $tokens[$key] = preg_replace('/\\\([&?!])/', "\\1", $val);
1813
+                    $sqlStr .= $tokens[$key];
1814
+                    break;
1815
+            } // switch
1816
+        } // foreach
1817
+
1818
+        $this->preparedTokens[] = array('tokens' => $tokens, 'tokenCount' => $count, 'sqlString' => $sqlStr);
1819
+        end($this->preparedTokens);
1820
+        return key($this->preparedTokens);
1821
+    }
1822
+
1823
+    /**
1824
+     * Takes a prepared stmt index and the data to replace and creates the query and runs it.
1825
+     *
1826
+     * @param  int		$stmt       The index of the prepared statement from preparedTokens
1827
+     * @param  array    $data 		The array of data to replace the tokens with.
1828
+     * @return resource result set or false on error
1829
+     */
1830
+    public function executePreparedQuery($stmt, $data = array())
1831
+    {
1832
+        if(!empty($this->preparedTokens[$stmt])){
1833
+            if(!is_array($data)){
1834
+                $data = array($data);
1835
+            }
1836
+
1837
+            $pTokens = $this->preparedTokens[$stmt];
1838
+
1839
+            //ensure that the number of data elements matches the number of replacement tokens
1840
+            //we found in prepare().
1841
+            if(count($data) != $pTokens['tokenCount']){
1842
+                //error the data count did not match the token count
1843
+                return false;
1844
+            }
1845
+
1846
+            $query = '';
1847
+            $dataIndex = 0;
1848
+            $tokens = $pTokens['tokens'];
1849
+            foreach ($tokens as $val) {
1850
+                switch ($val) {
1851
+                    case '?':
1852
+                        $query .= $this->quote($data[$dataIndex++]);
1853
+                        break;
1854
+                    case '&':
1855
+                        $filename = $data[$dataIndex++];
1856
+                        $query .= file_get_contents($filename);
1857
+                        break;
1858
+                    case '!':
1859
+                        $query .= $data[$dataIndex++];
1860
+                        break;
1861
+                    default:
1862
+                        $query .= $val;
1863
+                        break;
1864
+                }//switch
1865
+            }//foreach
1866
+            return $this->query($query);
1867
+        }else{
1868
+            return false;
1869
+        }
1870
+    }
1871
+
1872
+    /**
1873
+     * Run both prepare and execute without the client having to run both individually.
1874
+     *
1875
+     * @param  string	$sql        The sql to parse
1876
+     * @param  array    $data 		The array of data to replace the tokens with.
1877
+     * @return resource result set or false on error
1878
+     */
1879
+    public function pQuery($sql, $data = array())
1880
+    {
1881
+        $stmt = $this->prepareQuery($sql);
1882
+        return $this->executePreparedQuery($stmt, $data);
1883
+    }
1884 1884
 
1885 1885
 /********************** SQL FUNCTIONS ****************************/
1886 1886
     /**
@@ -1890,933 +1890,933 @@  discard block
 block discarded – undo
1890 1890
      * @param SugarBean $bean SugarBean instance
1891 1891
      * @return string SQL Create Table statement
1892 1892
      */
1893
-	public function createTableSQL(SugarBean $bean)
1894
-	{
1895
-		$tablename = $bean->getTableName();
1896
-		$fieldDefs = $bean->getFieldDefinitions();
1897
-		$indices = $bean->getIndices();
1898
-		return $this->createTableSQLParams($tablename, $fieldDefs, $indices);
1899
-	}
1900
-
1901
-	/**
1902
-	 * Generates SQL for insert statement.
1903
-	 *
1904
-	 * @param  SugarBean $bean SugarBean instance
1905
-	 * @return string SQL Create Table statement
1906
-	 */
1907
-	public function insertSQL(SugarBean $bean)
1908
-	{
1909
-		// get column names and values
1910
-		$sql = $this->insertParams($bean->getTableName(), $bean->getFieldDefinitions(), get_object_vars($bean),
1911
-		        isset($bean->field_name_map)?$bean->field_name_map:null, false);
1912
-		return $sql;
1913
-	}
1914
-
1915
-	/**
1916
-	 * Generates SQL for update statement.
1917
-	 *
1918
-	 * @param  SugarBean $bean SugarBean instance
1919
-	 * @param  array  $where Optional, where conditions in an array
1920
-	 * @return string SQL Create Table statement
1921
-	 */
1922
-	public function updateSQL(SugarBean $bean, array $where = array())
1923
-	{
1924
-		$primaryField = $bean->getPrimaryFieldDefinition();
1925
-		$columns = array();
1893
+    public function createTableSQL(SugarBean $bean)
1894
+    {
1895
+        $tablename = $bean->getTableName();
1896
+        $fieldDefs = $bean->getFieldDefinitions();
1897
+        $indices = $bean->getIndices();
1898
+        return $this->createTableSQLParams($tablename, $fieldDefs, $indices);
1899
+    }
1900
+
1901
+    /**
1902
+     * Generates SQL for insert statement.
1903
+     *
1904
+     * @param  SugarBean $bean SugarBean instance
1905
+     * @return string SQL Create Table statement
1906
+     */
1907
+    public function insertSQL(SugarBean $bean)
1908
+    {
1909
+        // get column names and values
1910
+        $sql = $this->insertParams($bean->getTableName(), $bean->getFieldDefinitions(), get_object_vars($bean),
1911
+                isset($bean->field_name_map)?$bean->field_name_map:null, false);
1912
+        return $sql;
1913
+    }
1914
+
1915
+    /**
1916
+     * Generates SQL for update statement.
1917
+     *
1918
+     * @param  SugarBean $bean SugarBean instance
1919
+     * @param  array  $where Optional, where conditions in an array
1920
+     * @return string SQL Create Table statement
1921
+     */
1922
+    public function updateSQL(SugarBean $bean, array $where = array())
1923
+    {
1924
+        $primaryField = $bean->getPrimaryFieldDefinition();
1925
+        $columns = array();
1926 1926
         $fields = $bean->getFieldDefinitions();
1927
-		// get column names and values
1928
-		foreach ($fields as $field => $fieldDef) {
1929
-			if (isset($fieldDef['source']) && $fieldDef['source'] != 'db')  continue;
1930
-			// Do not write out the id field on the update statement.
1931
-    		// We are not allowed to change ids.
1932
-    		if ($fieldDef['name'] == $primaryField['name']) continue;
1933
-
1934
-    		// If the field is an auto_increment field, then we shouldn't be setting it.  This was added
1935
-    		// specially for Bugs and Cases which have a number associated with them.
1936
-    		if (!empty($bean->field_name_map[$field]['auto_increment'])) continue;
1937
-
1938
-    		//custom fields handle their save separately
1939
-    		if(isset($bean->field_name_map) && !empty($bean->field_name_map[$field]['custom_type']))  continue;
1940
-
1941
-    		// no need to clear deleted since we only update not deleted records anyway
1942
-    		if($fieldDef['name'] == 'deleted' && empty($bean->deleted)) continue;
1943
-
1944
-    		if(isset($bean->$field)) {
1945
-    			$val = from_html($bean->$field);
1946
-    		} else {
1947
-    			continue;
1948
-    		}
1949
-
1950
-    		if(!empty($fieldDef['type']) && $fieldDef['type'] == 'bool'){
1951
-    			$val = $bean->getFieldValue($field);
1952
-    		}
1953
-
1954
-    		if(strlen($val) == 0) {
1955
-    			if(isset($fieldDef['default']) && strlen($fieldDef['default']) > 0) {
1956
-    				$val = $fieldDef['default'];
1957
-    			} else {
1958
-    				$val = null;
1959
-    			}
1960
-    		}
1961
-
1962
-    		if(!empty($val) && !empty($fieldDef['len']) && strlen($val) > $fieldDef['len']) {
1963
-			    $val = $this->truncate($val, $fieldDef['len']);
1964
-			}
1965
-		$columnName = $this->quoteIdentifier($fieldDef['name']);
1966
-    		if(!is_null($val) || !empty($fieldDef['required'])) {
1967
-    			$columns[] = "{$columnName}=".$this->massageValue($val, $fieldDef);
1968
-    		} elseif($this->isNullable($fieldDef)) {
1969
-    			$columns[] = "{$columnName}=NULL";
1970
-    		} else {
1971
-    		    $columns[] = "{$columnName}=".$this->emptyValue($fieldDef['type']);
1972
-    		}
1973
-		}
1974
-
1975
-		if ( sizeof($columns) == 0 )
1976
-			return ""; // no columns set
1977
-
1978
-		// build where clause
1979
-		$where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
1980
-		if(isset($fields['deleted'])) {
1981
-		    $where .= " AND deleted=0";
1982
-		}
1983
-
1984
-		return "UPDATE ".$bean->getTableName()."
1927
+        // get column names and values
1928
+        foreach ($fields as $field => $fieldDef) {
1929
+            if (isset($fieldDef['source']) && $fieldDef['source'] != 'db')  continue;
1930
+            // Do not write out the id field on the update statement.
1931
+            // We are not allowed to change ids.
1932
+            if ($fieldDef['name'] == $primaryField['name']) continue;
1933
+
1934
+            // If the field is an auto_increment field, then we shouldn't be setting it.  This was added
1935
+            // specially for Bugs and Cases which have a number associated with them.
1936
+            if (!empty($bean->field_name_map[$field]['auto_increment'])) continue;
1937
+
1938
+            //custom fields handle their save separately
1939
+            if(isset($bean->field_name_map) && !empty($bean->field_name_map[$field]['custom_type']))  continue;
1940
+
1941
+            // no need to clear deleted since we only update not deleted records anyway
1942
+            if($fieldDef['name'] == 'deleted' && empty($bean->deleted)) continue;
1943
+
1944
+            if(isset($bean->$field)) {
1945
+                $val = from_html($bean->$field);
1946
+            } else {
1947
+                continue;
1948
+            }
1949
+
1950
+            if(!empty($fieldDef['type']) && $fieldDef['type'] == 'bool'){
1951
+                $val = $bean->getFieldValue($field);
1952
+            }
1953
+
1954
+            if(strlen($val) == 0) {
1955
+                if(isset($fieldDef['default']) && strlen($fieldDef['default']) > 0) {
1956
+                    $val = $fieldDef['default'];
1957
+                } else {
1958
+                    $val = null;
1959
+                }
1960
+            }
1961
+
1962
+            if(!empty($val) && !empty($fieldDef['len']) && strlen($val) > $fieldDef['len']) {
1963
+                $val = $this->truncate($val, $fieldDef['len']);
1964
+            }
1965
+        $columnName = $this->quoteIdentifier($fieldDef['name']);
1966
+            if(!is_null($val) || !empty($fieldDef['required'])) {
1967
+                $columns[] = "{$columnName}=".$this->massageValue($val, $fieldDef);
1968
+            } elseif($this->isNullable($fieldDef)) {
1969
+                $columns[] = "{$columnName}=NULL";
1970
+            } else {
1971
+                $columns[] = "{$columnName}=".$this->emptyValue($fieldDef['type']);
1972
+            }
1973
+        }
1974
+
1975
+        if ( sizeof($columns) == 0 )
1976
+            return ""; // no columns set
1977
+
1978
+        // build where clause
1979
+        $where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
1980
+        if(isset($fields['deleted'])) {
1981
+            $where .= " AND deleted=0";
1982
+        }
1983
+
1984
+        return "UPDATE ".$bean->getTableName()."
1985 1985
 					SET ".implode(",", $columns)."
1986 1986
 					$where";
1987
-	}
1988
-
1989
-	/**
1990
-	 * This method returns a where array so that it has id entry if
1991
-	 * where is not an array or is empty
1992
-	 *
1993
-	 * @param  SugarBean $bean SugarBean instance
1994
-	 * @param  array  $where Optional, where conditions in an array
1995
-	 * @return array
1996
-	 */
1997
-	protected function updateWhereArray(SugarBean $bean, array $where = array())
1998
-	{
1999
-		if (count($where) == 0) {
2000
-			$fieldDef = $bean->getPrimaryFieldDefinition();
2001
-			$primaryColumn = $fieldDef['name'];
2002
-
2003
-			$val = $bean->getFieldValue($fieldDef['name']);
2004
-			if ($val != FALSE){
2005
-				$where[$primaryColumn] = $val;
2006
-			}
2007
-		}
2008
-
2009
-		return $where;
2010
-	}
2011
-
2012
-	/**
2013
-	 * Returns a where clause without the 'where' key word
2014
-	 *
2015
-	 * The clause returned does not have an 'and' at the beginning and the columns
2016
-	 * are joined by 'and'.
2017
-	 *
2018
-	 * @param  string $table table name
2019
-	 * @param  array  $whereArray Optional, where conditions in an array
2020
-	 * @return string
2021
-	 */
2022
-	protected function getColumnWhereClause($table, array $whereArray = array())
2023
-	{
2024
-		$where = array();
2025
-		foreach ($whereArray as $name => $val) {
2026
-			$op = "=";
2027
-			if (is_array($val)) {
2028
-				$op = "IN";
2029
-				$temp = array();
2030
-				foreach ($val as $tval){
2031
-					$temp[] = $this->quoted($tval);
2032
-				}
2033
-				$val = implode(",", $temp);
2034
-				$val = "($val)";
2035
-			} else {
2036
-				$val = $this->quoted($val);
2037
-			}
2038
-
2039
-			$where[] = " $table.$name $op $val";
2040
-		}
2041
-
2042
-		if (!empty($where))
2043
-			return implode(" AND ", $where);
2044
-
2045
-		return '';
2046
-	}
2047
-
2048
-	/**
2049
-	 * This method returns a complete where clause built from the
2050
-	 * where values specified.
2051
-	 *
2052
-	 * @param  SugarBean $bean SugarBean that describes the table
2053
-	 * @param  array  $whereArray Optional, where conditions in an array
2054
-	 * @return string
2055
-	 */
2056
-	protected function getWhereClause(SugarBean $bean, array $whereArray=array())
2057
-	{
2058
-	    return " WHERE " . $this->getColumnWhereClause($bean->getTableName(), $whereArray);
2059
-	}
2060
-
2061
-	/**
2062
-	 * Outputs a correct string for the sql statement according to value
2063
-	 *
2064
-	 * @param  mixed $val
2065
-	 * @param  array $fieldDef field definition
2066
-	 * @return mixed
2067
-	 */
2068
-	public function massageValue($val, $fieldDef)
2069
-	{
2070
-		$type = $this->getFieldType($fieldDef);
2071
-
2072
-		if(isset($this->type_class[$type])) {
2073
-			// handle some known types
2074
-			switch($this->type_class[$type]) {
2075
-				case 'bool':
2076
-				case 'int':
2077
-					if (!empty($fieldDef['required']) && $val == ''){
2078
-						if (isset($fieldDef['default'])){
2079
-							return $fieldDef['default'];
2080
-						}
2081
-						return 0;
2082
-					}
2083
-					return intval($val);
1987
+    }
1988
+
1989
+    /**
1990
+     * This method returns a where array so that it has id entry if
1991
+     * where is not an array or is empty
1992
+     *
1993
+     * @param  SugarBean $bean SugarBean instance
1994
+     * @param  array  $where Optional, where conditions in an array
1995
+     * @return array
1996
+     */
1997
+    protected function updateWhereArray(SugarBean $bean, array $where = array())
1998
+    {
1999
+        if (count($where) == 0) {
2000
+            $fieldDef = $bean->getPrimaryFieldDefinition();
2001
+            $primaryColumn = $fieldDef['name'];
2002
+
2003
+            $val = $bean->getFieldValue($fieldDef['name']);
2004
+            if ($val != FALSE){
2005
+                $where[$primaryColumn] = $val;
2006
+            }
2007
+        }
2008
+
2009
+        return $where;
2010
+    }
2011
+
2012
+    /**
2013
+     * Returns a where clause without the 'where' key word
2014
+     *
2015
+     * The clause returned does not have an 'and' at the beginning and the columns
2016
+     * are joined by 'and'.
2017
+     *
2018
+     * @param  string $table table name
2019
+     * @param  array  $whereArray Optional, where conditions in an array
2020
+     * @return string
2021
+     */
2022
+    protected function getColumnWhereClause($table, array $whereArray = array())
2023
+    {
2024
+        $where = array();
2025
+        foreach ($whereArray as $name => $val) {
2026
+            $op = "=";
2027
+            if (is_array($val)) {
2028
+                $op = "IN";
2029
+                $temp = array();
2030
+                foreach ($val as $tval){
2031
+                    $temp[] = $this->quoted($tval);
2032
+                }
2033
+                $val = implode(",", $temp);
2034
+                $val = "($val)";
2035
+            } else {
2036
+                $val = $this->quoted($val);
2037
+            }
2038
+
2039
+            $where[] = " $table.$name $op $val";
2040
+        }
2041
+
2042
+        if (!empty($where))
2043
+            return implode(" AND ", $where);
2044
+
2045
+        return '';
2046
+    }
2047
+
2048
+    /**
2049
+     * This method returns a complete where clause built from the
2050
+     * where values specified.
2051
+     *
2052
+     * @param  SugarBean $bean SugarBean that describes the table
2053
+     * @param  array  $whereArray Optional, where conditions in an array
2054
+     * @return string
2055
+     */
2056
+    protected function getWhereClause(SugarBean $bean, array $whereArray=array())
2057
+    {
2058
+        return " WHERE " . $this->getColumnWhereClause($bean->getTableName(), $whereArray);
2059
+    }
2060
+
2061
+    /**
2062
+     * Outputs a correct string for the sql statement according to value
2063
+     *
2064
+     * @param  mixed $val
2065
+     * @param  array $fieldDef field definition
2066
+     * @return mixed
2067
+     */
2068
+    public function massageValue($val, $fieldDef)
2069
+    {
2070
+        $type = $this->getFieldType($fieldDef);
2071
+
2072
+        if(isset($this->type_class[$type])) {
2073
+            // handle some known types
2074
+            switch($this->type_class[$type]) {
2075
+                case 'bool':
2076
+                case 'int':
2077
+                    if (!empty($fieldDef['required']) && $val == ''){
2078
+                        if (isset($fieldDef['default'])){
2079
+                            return $fieldDef['default'];
2080
+                        }
2081
+                        return 0;
2082
+                    }
2083
+                    return intval($val);
2084 2084
                 case 'bigint' :
2085 2085
                     $val = (float)$val;
2086
-					if (!empty($fieldDef['required']) && $val == false){
2087
-						if (isset($fieldDef['default'])){
2088
-							return $fieldDef['default'];
2089
-						}
2090
-						return 0;
2091
-					}
2086
+                    if (!empty($fieldDef['required']) && $val == false){
2087
+                        if (isset($fieldDef['default'])){
2088
+                            return $fieldDef['default'];
2089
+                        }
2090
+                        return 0;
2091
+                    }
2092 2092
                     return $val;
2093
-				case 'float':
2094
-					if (!empty($fieldDef['required'])  && $val == ''){
2095
-						if (isset($fieldDef['default'])){
2096
-							return $fieldDef['default'];
2097
-						}
2098
-						return 0;
2099
-					}
2100
-					return floatval($val);
2101
-				case 'time':
2102
-				case 'date':
2103
-					// empty date can't be '', so convert it to either NULL or empty date value
2104
-					if($val == '') {
2105
-						if (!empty($fieldDef['required'])) {
2106
-							if (isset($fieldDef['default'])) {
2107
-								return $fieldDef['default'];
2108
-							}
2109
-							return $this->emptyValue($type);
2110
-						}
2111
-						return "NULL";
2112
-					}
2113
-					break;
2114
-			}
2115
-		} else {
2116
-		    if(!empty($val) && !empty($fieldDef['len']) && strlen($val) > $fieldDef['len']) {
2117
-			    $val = $this->truncate($val, $fieldDef['len']);
2118
-			}
2119
-		}
2120
-
2121
-		if ( is_null($val) ) {
2122
-			if(!empty($fieldDef['required'])) {
2123
-				if (isset($fieldDef['default'])){
2124
-					return $fieldDef['default'];
2125
-				}
2126
-				return $this->emptyValue($type);
2127
-			} else {
2128
-				return "NULL";
2129
-			}
2130
-		}
2093
+                case 'float':
2094
+                    if (!empty($fieldDef['required'])  && $val == ''){
2095
+                        if (isset($fieldDef['default'])){
2096
+                            return $fieldDef['default'];
2097
+                        }
2098
+                        return 0;
2099
+                    }
2100
+                    return floatval($val);
2101
+                case 'time':
2102
+                case 'date':
2103
+                    // empty date can't be '', so convert it to either NULL or empty date value
2104
+                    if($val == '') {
2105
+                        if (!empty($fieldDef['required'])) {
2106
+                            if (isset($fieldDef['default'])) {
2107
+                                return $fieldDef['default'];
2108
+                            }
2109
+                            return $this->emptyValue($type);
2110
+                        }
2111
+                        return "NULL";
2112
+                    }
2113
+                    break;
2114
+            }
2115
+        } else {
2116
+            if(!empty($val) && !empty($fieldDef['len']) && strlen($val) > $fieldDef['len']) {
2117
+                $val = $this->truncate($val, $fieldDef['len']);
2118
+            }
2119
+        }
2120
+
2121
+        if ( is_null($val) ) {
2122
+            if(!empty($fieldDef['required'])) {
2123
+                if (isset($fieldDef['default'])){
2124
+                    return $fieldDef['default'];
2125
+                }
2126
+                return $this->emptyValue($type);
2127
+            } else {
2128
+                return "NULL";
2129
+            }
2130
+        }
2131 2131
         if($type == "datetimecombo") {
2132 2132
             $type = "datetime";
2133 2133
         }
2134
-		return $this->convert($this->quoted($val), $type);
2135
-	}
2136
-
2137
-	/**
2138
-	 * Massages the field defintions to fill in anything else the DB backend may add
2139
-	 *
2140
-	 * @param  array  $fieldDef
2141
-	 * @param  string $tablename
2142
-	 * @return array
2143
-	 */
2144
-	public function massageFieldDef(&$fieldDef, $tablename)
2145
-	{
2146
-		if ( !isset($fieldDef['dbType']) ) {
2147
-			if ( isset($fieldDef['dbtype']) )
2148
-				$fieldDef['dbType'] = $fieldDef['dbtype'];
2149
-			else
2150
-				$fieldDef['dbType'] = $fieldDef['type'];
2151
-		}
2152
-		$type = $this->getColumnType($fieldDef['dbType'],$fieldDef['name'],$tablename);
2153
-		$matches = array();
2134
+        return $this->convert($this->quoted($val), $type);
2135
+    }
2136
+
2137
+    /**
2138
+     * Massages the field defintions to fill in anything else the DB backend may add
2139
+     *
2140
+     * @param  array  $fieldDef
2141
+     * @param  string $tablename
2142
+     * @return array
2143
+     */
2144
+    public function massageFieldDef(&$fieldDef, $tablename)
2145
+    {
2146
+        if ( !isset($fieldDef['dbType']) ) {
2147
+            if ( isset($fieldDef['dbtype']) )
2148
+                $fieldDef['dbType'] = $fieldDef['dbtype'];
2149
+            else
2150
+                $fieldDef['dbType'] = $fieldDef['type'];
2151
+        }
2152
+        $type = $this->getColumnType($fieldDef['dbType'],$fieldDef['name'],$tablename);
2153
+        $matches = array();
2154 2154
         // len can be a number or a string like 'max', for example, nvarchar(max)
2155 2155
         preg_match_all('/(\w+)(?:\(([0-9]+,?[0-9]*|\w+)\)|)/i', $type, $matches);
2156
-		if ( isset($matches[1][0]) )
2157
-			$fieldDef['type'] = $matches[1][0];
2158
-		if ( isset($matches[2][0]) && empty($fieldDef['len']) )
2159
-			$fieldDef['len'] = $matches[2][0];
2160
-		if ( !empty($fieldDef['precision']) && is_numeric($fieldDef['precision']) && !strstr($fieldDef['len'],',') )
2161
-			$fieldDef['len'] .= ",{$fieldDef['precision']}";
2162
-		if (!empty($fieldDef['required']) || ($fieldDef['name'] == 'id' && !isset($fieldDef['required'])) ) {
2163
-			$fieldDef['required'] = 'true';
2164
-		}
2165
-	}
2166
-
2167
-	/**
2168
-	 * Take an SQL statement and produce a list of fields used in that select
2169
-	 * @param string $selectStatement
2170
-	 * @return array
2171
-	 */
2172
-	public function getSelectFieldsFromQuery($selectStatement)
2173
-	{
2174
-		$selectStatement = trim($selectStatement);
2175
-		if (strtoupper(substr($selectStatement, 0, 6)) == "SELECT")
2176
-			$selectStatement = trim(substr($selectStatement, 6));
2177
-
2178
-		//Due to sql functions existing in many selects, we can't use php explode
2179
-		$fields = array();
2180
-		$level = 0;
2181
-		$selectField = "";
2182
-		$strLen = strlen($selectStatement);
2183
-		for($i = 0; $i < $strLen; $i++)
2184
-		{
2185
-			$char = $selectStatement[$i];
2186
-
2187
-			if ($char == "," && $level == 0)
2188
-			{
2189
-				$field = $this->getFieldNameFromSelect(trim($selectField));
2190
-				$fields[$field] = $selectField;
2191
-				$selectField = "";
2192
-			}
2193
-			else if ($char == "("){
2194
-				$level++;
2195
-				$selectField .= $char;
2196
-			}
2197
-			else if($char == ")"){
2198
-				$level--;
2199
-				$selectField .= $char;
2200
-
2201
-
2202
-			}else{
2203
-				$selectField .= $char;
2204
-			}
2205
-
2206
-		}
2207
-		$fields[$this->getFieldNameFromSelect($selectField)] = $selectField;
2208
-		return $fields;
2209
-	}
2210
-
2211
-	/**
2212
-	 * returns the field name used in a select
2213
-	 * @param string $string SELECT query
2156
+        if ( isset($matches[1][0]) )
2157
+            $fieldDef['type'] = $matches[1][0];
2158
+        if ( isset($matches[2][0]) && empty($fieldDef['len']) )
2159
+            $fieldDef['len'] = $matches[2][0];
2160
+        if ( !empty($fieldDef['precision']) && is_numeric($fieldDef['precision']) && !strstr($fieldDef['len'],',') )
2161
+            $fieldDef['len'] .= ",{$fieldDef['precision']}";
2162
+        if (!empty($fieldDef['required']) || ($fieldDef['name'] == 'id' && !isset($fieldDef['required'])) ) {
2163
+            $fieldDef['required'] = 'true';
2164
+        }
2165
+    }
2166
+
2167
+    /**
2168
+     * Take an SQL statement and produce a list of fields used in that select
2169
+     * @param string $selectStatement
2170
+     * @return array
2171
+     */
2172
+    public function getSelectFieldsFromQuery($selectStatement)
2173
+    {
2174
+        $selectStatement = trim($selectStatement);
2175
+        if (strtoupper(substr($selectStatement, 0, 6)) == "SELECT")
2176
+            $selectStatement = trim(substr($selectStatement, 6));
2177
+
2178
+        //Due to sql functions existing in many selects, we can't use php explode
2179
+        $fields = array();
2180
+        $level = 0;
2181
+        $selectField = "";
2182
+        $strLen = strlen($selectStatement);
2183
+        for($i = 0; $i < $strLen; $i++)
2184
+        {
2185
+            $char = $selectStatement[$i];
2186
+
2187
+            if ($char == "," && $level == 0)
2188
+            {
2189
+                $field = $this->getFieldNameFromSelect(trim($selectField));
2190
+                $fields[$field] = $selectField;
2191
+                $selectField = "";
2192
+            }
2193
+            else if ($char == "("){
2194
+                $level++;
2195
+                $selectField .= $char;
2196
+            }
2197
+            else if($char == ")"){
2198
+                $level--;
2199
+                $selectField .= $char;
2200
+
2201
+
2202
+            }else{
2203
+                $selectField .= $char;
2204
+            }
2205
+
2206
+        }
2207
+        $fields[$this->getFieldNameFromSelect($selectField)] = $selectField;
2208
+        return $fields;
2209
+    }
2210
+
2211
+    /**
2212
+     * returns the field name used in a select
2213
+     * @param string $string SELECT query
2214 2214
      * @return string
2215 2215
      */
2216
-	protected function getFieldNameFromSelect($string)
2217
-	{
2218
-		if(strncasecmp($string, "DISTINCT ", 9) == 0) {
2219
-			$string = substr($string, 9);
2220
-		}
2221
-		if (stripos($string, " as ") !== false)
2222
-			//"as" used for an alias
2223
-			return trim(substr($string, strripos($string, " as ") + 4));
2224
-		else if (strrpos($string, " ") != 0)
2225
-			//Space used as a delimiter for an alias
2226
-			return trim(substr($string, strrpos($string, " ")));
2227
-		else if (strpos($string, ".") !== false)
2228
-			//No alias, but a table.field format was used
2229
-			return substr($string, strpos($string, ".") + 1);
2230
-		else
2231
-			//Give up and assume the whole thing is the field name
2232
-			return $string;
2233
-	}
2234
-
2235
-	/**
2236
-	 * Generates SQL for delete statement identified by id.
2237
-	 *
2238
-	 * @param  SugarBean $bean SugarBean instance
2239
-	 * @param  array  $where where conditions in an array
2240
-	 * @return string SQL Update Statement
2241
-	 */
2242
-	public function deleteSQL(SugarBean $bean, array $where)
2243
-	{
2244
-		$where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
2245
-		return "UPDATE ".$bean->getTableName()." SET deleted=1 $where";
2246
-	}
2216
+    protected function getFieldNameFromSelect($string)
2217
+    {
2218
+        if(strncasecmp($string, "DISTINCT ", 9) == 0) {
2219
+            $string = substr($string, 9);
2220
+        }
2221
+        if (stripos($string, " as ") !== false)
2222
+            //"as" used for an alias
2223
+            return trim(substr($string, strripos($string, " as ") + 4));
2224
+        else if (strrpos($string, " ") != 0)
2225
+            //Space used as a delimiter for an alias
2226
+            return trim(substr($string, strrpos($string, " ")));
2227
+        else if (strpos($string, ".") !== false)
2228
+            //No alias, but a table.field format was used
2229
+            return substr($string, strpos($string, ".") + 1);
2230
+        else
2231
+            //Give up and assume the whole thing is the field name
2232
+            return $string;
2233
+    }
2234
+
2235
+    /**
2236
+     * Generates SQL for delete statement identified by id.
2237
+     *
2238
+     * @param  SugarBean $bean SugarBean instance
2239
+     * @param  array  $where where conditions in an array
2240
+     * @return string SQL Update Statement
2241
+     */
2242
+    public function deleteSQL(SugarBean $bean, array $where)
2243
+    {
2244
+        $where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
2245
+        return "UPDATE ".$bean->getTableName()." SET deleted=1 $where";
2246
+    }
2247
+
2248
+    /**
2249
+     * Generates SQL for select statement for any bean identified by id.
2250
+     *
2251
+     * @param  SugarBean $bean SugarBean instance
2252
+     * @param  array  $where where conditions in an array
2253
+     * @return string SQL Select Statement
2254
+     */
2255
+    public function retrieveSQL(SugarBean $bean, array $where)
2256
+    {
2257
+        $where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
2258
+        return "SELECT * FROM ".$bean->getTableName()." $where AND deleted=0";
2259
+    }
2260
+
2261
+    /**
2262
+     * This method implements a generic sql for a collection of beans.
2263
+     *
2264
+     * Currently, this function does not support outer joins.
2265
+     *
2266
+     * @param array $beans Array of values returned by get_class method as the keys and a bean as
2267
+     *      the value for that key. These beans will be joined in the sql by the key
2268
+     *      attribute of field defs.
2269
+     * @param  array $cols Optional, columns to be returned with the keys as names of bean
2270
+     *      as identified by get_class of bean. Values of this array is the array of fieldDefs
2271
+     *      to be returned for a bean. If an empty array is passed, all columns are selected.
2272
+     * @param  array $whereClause Optional, values with the keys as names of bean as identified
2273
+     *      by get_class of bean. Each value at the first level is an array of values for that
2274
+     *      bean identified by name of fields. If we want to pass multiple values for a name,
2275
+     *      pass it as an array. If where is not passed, all the rows will be returned.
2276
+     *
2277
+     * @return string SQL Select Statement
2278
+     */
2279
+    public function retrieveViewSQL(array $beans, array $cols = array(), array $whereClause = array())
2280
+    {
2281
+        $relations = array(); // stores relations between tables as they are discovered
2282
+        $where = $select = array();
2283
+        foreach ($beans as $beanID => $bean) {
2284
+            $tableName = $bean->getTableName();
2285
+            $beanTables[$beanID] = $tableName;
2286
+
2287
+            $table = $beanID;
2288
+            $tables[$table] = $tableName;
2289
+            $aliases[$tableName][] = $table;
2290
+
2291
+            // build part of select for this table
2292
+            if (is_array($cols[$beanID]))
2293
+                foreach ($cols[$beanID] as $def) $select[] = $table.".".$def['name'];
2294
+
2295
+            // build part of where clause
2296
+            if (is_array($whereClause[$beanID])){
2297
+                $where[] = $this->getColumnWhereClause($table, $whereClause[$beanID]);
2298
+            }
2299
+            // initialize so that it can be used properly in form clause generation
2300
+            $table_used_in_from[$table] = false;
2301
+
2302
+            $indices = $bean->getIndices();
2303
+            foreach ($indices as $index){
2304
+                if ($index['type'] == 'foreign') {
2305
+                    $relationship[$table][] = array('foreignTable'=> $index['foreignTable']
2306
+                                                ,'foreignColumn'=>$index['foreignField']
2307
+                                                ,'localColumn'=> $index['fields']
2308
+                                                );
2309
+                }
2310
+            }
2311
+            $where[] = " $table.deleted = 0";
2312
+        }
2313
+
2314
+        // join these clauses
2315
+        $select = !empty($select) ? implode(",", $select) : "*";
2316
+        $where = implode(" AND ", $where);
2317
+
2318
+        // generate the from clause. Use relations array to generate outer joins
2319
+        // all the rest of the tables will be used as a simple from
2320
+        // relations table define relations between table1 and table2 through column on table 1
2321
+        // table2 is assumed to joining through primary key called id
2322
+        $separator = "";
2323
+        $from = ''; $table_used_in_from = array();
2324
+        foreach ($relations as $table1 => $rightsidearray){
2325
+            if ($table_used_in_from[$table1]) continue; // table has been joined
2326
+
2327
+            $from .= $separator." ".$table1;
2328
+            $table_used_in_from[$table1] = true;
2329
+            foreach ($rightsidearray as $tablearray){
2330
+                $table2 = $tablearray['foreignTable']; // get foreign table
2331
+                $tableAlias = $aliases[$table2]; // get a list of aliases for this table
2332
+                foreach ($tableAlias as $table2) {
2333
+                    //choose first alias that does not match
2334
+                    // we are doing this because of self joins.
2335
+                    // in case of self joins, the same table will have many aliases.
2336
+                    if ($table2 != $table1) break;
2337
+                }
2338
+
2339
+                $col = $tablearray['foreingColumn'];
2340
+                $name = $tablearray['localColumn'];
2341
+                $from .= " LEFT JOIN $table on ($table1.$name = $table2.$col)";
2342
+                $table_used_in_from[$table2] = true;
2343
+            }
2344
+            $separator = ",";
2345
+        }
2346
+
2347
+        return "SELECT $select FROM $from WHERE $where";
2348
+    }
2349
+
2350
+    /**
2351
+     * Generates SQL for create index statement for a bean.
2352
+     *
2353
+     * @param  SugarBean $bean SugarBean instance
2354
+     * @param  array  $fields fields used in the index
2355
+     * @param  string $name index name
2356
+     * @param  bool   $unique Optional, set to true if this is an unique index
2357
+     * @return string SQL Select Statement
2358
+     */
2359
+    public function createIndexSQL(SugarBean $bean, array $fields, $name, $unique = true)
2360
+    {
2361
+        $unique = ($unique) ? "unique" : "";
2362
+        $tablename = $bean->getTableName();
2363
+        $columns = array();
2364
+        // get column names
2365
+        foreach ($fields as $fieldDef)
2366
+            $columns[] = $fieldDef['name'];
2367
+
2368
+        if (empty($columns))
2369
+            return "";
2370
+
2371
+        $columns = implode(",", $columns);
2372
+
2373
+        return "CREATE $unique INDEX $name ON $tablename ($columns)";
2374
+    }
2375
+
2376
+    /**
2377
+     * Returns the type of the variable in the field
2378
+     *
2379
+     * @param  array $fieldDef Vardef-format field def
2380
+     * @return string
2381
+     */
2382
+    public function getFieldType($fieldDef)
2383
+    {
2384
+        // get the type for db type. if that is not set,
2385
+        // get it from type. This is done so that
2386
+        // we do not have change a lot of existing code
2387
+        // and add dbtype where type is being used for some special
2388
+        // purposes like referring to foreign table etc.
2389
+        if(!empty($fieldDef['dbType']))
2390
+            return  $fieldDef['dbType'];
2391
+        if(!empty($fieldDef['dbtype']))
2392
+            return  $fieldDef['dbtype'];
2393
+        if (!empty($fieldDef['type']))
2394
+            return  $fieldDef['type'];
2395
+        if (!empty($fieldDef['Type']))
2396
+            return  $fieldDef['Type'];
2397
+        if (!empty($fieldDef['data_type']))
2398
+            return  $fieldDef['data_type'];
2399
+
2400
+        return null;
2401
+    }
2402
+
2403
+    /**
2404
+     * retrieves the different components from the passed column type as it is used in the type mapping and vardefs
2405
+     * type format: <baseType>[(<len>[,<scale>])]
2406
+     * @param string $type Column type
2407
+     * @return array|bool array containing the different components of the passed in type or false in case the type contains illegal characters
2408
+     */
2409
+    public function getTypeParts($type)
2410
+    {
2411
+        if(preg_match("#(?P<type>\w+)\s*(?P<arg>\((?P<len>\w+)\s*(,\s*(?P<scale>\d+))*\))*#", $type, $matches))
2412
+        {
2413
+            $return = array();  // Not returning matches array as such as we don't want to expose the regex make up on the interface
2414
+            $return['baseType'] = $matches['type'];
2415
+            if( isset($matches['arg'])) {
2416
+                $return['arg'] = $matches['arg'];
2417
+            }
2418
+            if( isset($matches['len'])) {
2419
+                $return['len'] = $matches['len'];
2420
+            }
2421
+            if( isset($matches['scale'])) {
2422
+                $return['scale'] = $matches['scale'];
2423
+            }
2424
+            return $return;
2425
+        } else {
2426
+            return false;
2427
+        }
2428
+    }
2429
+
2430
+    /**
2431
+     * Returns the defintion for a single column
2432
+     *
2433
+     * @param  array  $fieldDef Vardef-format field def
2434
+     * @param  bool   $ignoreRequired  Optional, true if we should ignore this being a required field
2435
+     * @param  string $table           Optional, table name
2436
+     * @param  bool   $return_as_array Optional, true if we should return the result as an array instead of sql
2437
+     * @return string or array if $return_as_array is true
2438
+     */
2439
+    protected function oneColumnSQLRep($fieldDef, $ignoreRequired = false, $table = '', $return_as_array = false)
2440
+    {
2441
+        $name = $fieldDef['name'];
2442
+        $type = $this->getFieldType($fieldDef);
2443
+        $colType = $this->getColumnType($type);
2444
+
2445
+        if($parts = $this->getTypeParts($colType))
2446
+        {
2447
+            $colBaseType = $parts['baseType'];
2448
+            $defLen =  isset($parts['len']) ? $parts['len'] : '255'; // Use the mappings length (precision) as default if it exists
2449
+        }
2450
+
2451
+        if(!empty($fieldDef['len'])) {
2452
+            if (in_array($colBaseType, array( 'nvarchar', 'nchar', 'varchar', 'varchar2', 'char',
2453
+                                            'clob', 'blob', 'text'))) {
2454
+                    $colType = "$colBaseType(${fieldDef['len']})";
2455
+            } elseif(($colBaseType == 'decimal' || $colBaseType == 'float')){
2456
+                    if(!empty($fieldDef['precision']) && is_numeric($fieldDef['precision']))
2457
+                        if(strpos($fieldDef['len'],',') === false){
2458
+                            $colType = $colBaseType . "(".$fieldDef['len'].",".$fieldDef['precision'].")";
2459
+                        }else{
2460
+                            $colType = $colBaseType . "(".$fieldDef['len'].")";
2461
+                        }
2462
+                    else
2463
+                            $colType = $colBaseType . "(".$fieldDef['len'].")";
2464
+                }
2465
+        } else {
2466
+            if (in_array($colBaseType, array( 'nvarchar', 'nchar', 'varchar', 'varchar2', 'char'))) {
2467
+                $colType = "$colBaseType($defLen)";
2468
+            }
2469
+        }
2470
+
2471
+        $default = '';
2472
+
2473
+        // Bug #52610 We should have ability don't add DEFAULT part to query for boolean fields
2474
+        if (!empty($fieldDef['no_default']))
2475
+        {
2476
+            // nothing to do
2477
+        }
2478
+        elseif (isset($fieldDef['default']) && strlen($fieldDef['default']) > 0)
2479
+        {
2480
+            $default = " DEFAULT ".$this->quoted($fieldDef['default']);
2481
+        }
2482
+        elseif (!isset($default) && $type == 'bool')
2483
+        {
2484
+            $default = " DEFAULT 0 ";
2485
+        }
2486
+
2487
+        $auto_increment = '';
2488
+        if(!empty($fieldDef['auto_increment']) && $fieldDef['auto_increment'])
2489
+            $auto_increment = $this->setAutoIncrement($table , $fieldDef['name']);
2490
+
2491
+        $required = 'NULL';  // MySQL defaults to NULL, SQL Server defaults to NOT NULL -- must specify
2492
+        //Starting in 6.0, only ID and auto_increment fields will be NOT NULL in the DB.
2493
+        if ((empty($fieldDef['isnull']) || strtolower($fieldDef['isnull']) == 'false') &&
2494
+            (!empty($auto_increment) || $name == 'id' || ($fieldDef['type'] == 'id' && !empty($fieldDef['required'])))) {
2495
+            $required =  "NOT NULL";
2496
+        }
2497
+        // If the field is marked both required & isnull=>false - alwqys make it not null
2498
+        // Use this to ensure primary key fields never defined as null
2499
+        if(isset($fieldDef['isnull']) && (strtolower($fieldDef['isnull']) == 'false' || $fieldDef['isnull'] === false)
2500
+            && !empty($fieldDef['required'])) {
2501
+            $required =  "NOT NULL";
2502
+        }
2503
+        if ($ignoreRequired)
2504
+            $required = "";
2505
+
2506
+        if ( $return_as_array ) {
2507
+            return array(
2508
+                'name' => $name,
2509
+                'colType' => $colType,
2510
+                'colBaseType' => $colBaseType,  // Adding base type for easier processing in derived classes
2511
+                'default' => $default,
2512
+                'required' => $required,
2513
+                'auto_increment' => $auto_increment,
2514
+                'full' => "$name $colType $default $required $auto_increment",
2515
+                );
2516
+        } else {
2517
+            return "$name $colType $default $required $auto_increment";
2518
+        }
2519
+    }
2520
+
2521
+    /**
2522
+     * Returns SQL defintions for all columns in a table
2523
+     *
2524
+     * @param  array  $fieldDefs  Vardef-format field def
2525
+     * @param  bool   $ignoreRequired Optional, true if we should ignor this being a required field
2526
+     * @param  string $tablename      Optional, table name
2527
+     * @return string SQL column definitions
2528
+     */
2529
+    protected function columnSQLRep($fieldDefs, $ignoreRequired = false, $tablename)
2530
+    {
2531
+        $columns = array();
2532
+
2533
+        if ($this->isFieldArray($fieldDefs)) {
2534
+            foreach ($fieldDefs as $fieldDef) {
2535
+                if(!isset($fieldDef['source']) || $fieldDef['source'] == 'db') {
2536
+                    $columns[] = $this->oneColumnSQLRep($fieldDef,false, $tablename);
2537
+                }
2538
+            }
2539
+            $columns = implode(",", $columns);
2540
+        }
2541
+        else {
2542
+            $columns = $this->oneColumnSQLRep($fieldDefs,$ignoreRequired, $tablename);
2543
+        }
2544
+
2545
+        return $columns;
2546
+    }
2547
+
2548
+    /**
2549
+     * Returns the next value for an auto increment
2550
+     * @abstract
2551
+     * @param  string $table Table name
2552
+     * @param  string $field_name Field name
2553
+     * @return string
2554
+     */
2555
+    public function getAutoIncrement($table, $field_name)
2556
+    {
2557
+        return "";
2558
+    }
2559
+
2560
+    /**
2561
+     * Returns the sql for the next value in a sequence
2562
+     * @abstract
2563
+     * @param  string $table  Table name
2564
+     * @param  string $field_name  Field name
2565
+     * @return string
2566
+     */
2567
+    public function getAutoIncrementSQL($table, $field_name)
2568
+    {
2569
+        return "";
2570
+    }
2571
+
2572
+    /**
2573
+     * Either creates an auto increment through queries or returns sql for auto increment
2574
+     * that can be appended to the end of column defination (mysql)
2575
+     * @abstract
2576
+     * @param  string $table Table name
2577
+     * @param  string $field_name Field name
2578
+     * @return string
2579
+     */
2580
+    protected function setAutoIncrement($table, $field_name)
2581
+    {
2582
+        $this->deleteAutoIncrement($table, $field_name);
2583
+        return "";
2584
+    }
2585
+
2586
+    /**
2587
+     * Sets the next auto-increment value of a column to a specific value.
2588
+     * @abstract
2589
+     * @param  string $table Table name
2590
+     * @param  string $field_name Field name
2591
+     * @param  int $start_value  Starting autoincrement value
2592
+     * @return string
2593
+     *
2594
+     */
2595
+    public function setAutoIncrementStart($table, $field_name, $start_value)
2596
+    {
2597
+        return "";
2598
+    }
2599
+
2600
+    /**
2601
+     * Deletes an auto increment
2602
+     * @abstract
2603
+     * @param string $table tablename
2604
+     * @param string $field_name
2605
+     */
2606
+    public function deleteAutoIncrement($table, $field_name)
2607
+    {
2608
+        return;
2609
+    }
2610
+
2611
+    /**
2612
+     * This method generates sql for adding a column to table identified by field def.
2613
+     *
2614
+     * @param  string $tablename
2615
+     * @param  array  $fieldDefs
2616
+     * @return string SQL statement
2617
+     */
2618
+    public function addColumnSQL($tablename, $fieldDefs)
2619
+    {
2620
+        return $this->changeColumnSQL($tablename, $fieldDefs, 'add');
2621
+    }
2622
+
2623
+    /**
2624
+     * This method genrates sql for altering old column identified by oldFieldDef to new fieldDef.
2625
+     *
2626
+     * @param  string $tablename
2627
+     * @param  array  $newFieldDefs
2628
+     * @param  bool  $ignorerequired Optional, true if we should ignor this being a required field
2629
+     * @return string|array SQL statement(s)
2630
+     */
2631
+    public function alterColumnSQL($tablename, $newFieldDefs, $ignorerequired = false)
2632
+    {
2633
+        return $this->changeColumnSQL($tablename, $newFieldDefs, 'modify', $ignorerequired);
2634
+    }
2247 2635
 
2248 2636
     /**
2249
-     * Generates SQL for select statement for any bean identified by id.
2637
+     * Generates SQL for dropping a table.
2250 2638
      *
2251
-     * @param  SugarBean $bean SugarBean instance
2252
-     * @param  array  $where where conditions in an array
2253
-     * @return string SQL Select Statement
2639
+     * @param  SugarBean $bean Sugarbean instance
2640
+     * @return string SQL statement
2254 2641
      */
2255
-	public function retrieveSQL(SugarBean $bean, array $where)
2256
-	{
2257
-		$where = $this->getWhereClause($bean, $this->updateWhereArray($bean, $where));
2258
-		return "SELECT * FROM ".$bean->getTableName()." $where AND deleted=0";
2259
-	}
2642
+    public function dropTableSQL(SugarBean $bean)
2643
+    {
2644
+        return $this->dropTableNameSQL($bean->getTableName());
2645
+    }
2260 2646
 
2261 2647
     /**
2262
-     * This method implements a generic sql for a collection of beans.
2648
+     * Generates SQL for dropping a table.
2263 2649
      *
2264
-     * Currently, this function does not support outer joins.
2650
+     * @param  string $name table name
2651
+     * @return string SQL statement
2652
+     */
2653
+    public function dropTableNameSQL($name)
2654
+    {
2655
+        return "DROP TABLE ".$name;
2656
+    }
2657
+
2658
+    /**
2659
+     * Generates SQL for truncating a table.
2660
+     * @param  string $name  table name
2661
+     * @return string
2662
+     */
2663
+    public function truncateTableSQL($name)
2664
+    {
2665
+        return "TRUNCATE $name";
2666
+    }
2667
+
2668
+    /**
2669
+     * This method generates sql that deletes a column identified by fieldDef.
2265 2670
      *
2266
-     * @param array $beans Array of values returned by get_class method as the keys and a bean as
2267
-     *      the value for that key. These beans will be joined in the sql by the key
2268
-     *      attribute of field defs.
2269
-     * @param  array $cols Optional, columns to be returned with the keys as names of bean
2270
-     *      as identified by get_class of bean. Values of this array is the array of fieldDefs
2271
-     *      to be returned for a bean. If an empty array is passed, all columns are selected.
2272
-     * @param  array $whereClause Optional, values with the keys as names of bean as identified
2273
-     *      by get_class of bean. Each value at the first level is an array of values for that
2274
-     *      bean identified by name of fields. If we want to pass multiple values for a name,
2275
-     *      pass it as an array. If where is not passed, all the rows will be returned.
2671
+     * @param  SugarBean $bean      Sugarbean instance
2672
+     * @param  array  $fieldDefs
2673
+     * @return string SQL statement
2674
+     */
2675
+    public function deleteColumnSQL(SugarBean $bean, $fieldDefs)
2676
+    {
2677
+        return $this->dropColumnSQL($bean->getTableName(), $fieldDefs);
2678
+    }
2679
+
2680
+    /**
2681
+     * This method generates sql that drops a column identified by fieldDef.
2682
+     * Designed to work like the other addColumnSQL() and alterColumnSQL() functions
2276 2683
      *
2277
-     * @return string SQL Select Statement
2684
+     * @param  string $tablename
2685
+     * @param  array  $fieldDefs
2686
+     * @return string SQL statement
2278 2687
      */
2279
-	public function retrieveViewSQL(array $beans, array $cols = array(), array $whereClause = array())
2280
-	{
2281
-		$relations = array(); // stores relations between tables as they are discovered
2282
-		$where = $select = array();
2283
-		foreach ($beans as $beanID => $bean) {
2284
-			$tableName = $bean->getTableName();
2285
-			$beanTables[$beanID] = $tableName;
2286
-
2287
-			$table = $beanID;
2288
-			$tables[$table] = $tableName;
2289
-			$aliases[$tableName][] = $table;
2290
-
2291
-			// build part of select for this table
2292
-			if (is_array($cols[$beanID]))
2293
-				foreach ($cols[$beanID] as $def) $select[] = $table.".".$def['name'];
2294
-
2295
-			// build part of where clause
2296
-			if (is_array($whereClause[$beanID])){
2297
-				$where[] = $this->getColumnWhereClause($table, $whereClause[$beanID]);
2298
-			}
2299
-			// initialize so that it can be used properly in form clause generation
2300
-			$table_used_in_from[$table] = false;
2301
-
2302
-			$indices = $bean->getIndices();
2303
-			foreach ($indices as $index){
2304
-				if ($index['type'] == 'foreign') {
2305
-					$relationship[$table][] = array('foreignTable'=> $index['foreignTable']
2306
-												,'foreignColumn'=>$index['foreignField']
2307
-												,'localColumn'=> $index['fields']
2308
-												);
2309
-				}
2310
-			}
2311
-			$where[] = " $table.deleted = 0";
2312
-		}
2313
-
2314
-		// join these clauses
2315
-		$select = !empty($select) ? implode(",", $select) : "*";
2316
-		$where = implode(" AND ", $where);
2317
-
2318
-		// generate the from clause. Use relations array to generate outer joins
2319
-		// all the rest of the tables will be used as a simple from
2320
-		// relations table define relations between table1 and table2 through column on table 1
2321
-		// table2 is assumed to joining through primary key called id
2322
-		$separator = "";
2323
-		$from = ''; $table_used_in_from = array();
2324
-		foreach ($relations as $table1 => $rightsidearray){
2325
-			if ($table_used_in_from[$table1]) continue; // table has been joined
2326
-
2327
-			$from .= $separator." ".$table1;
2328
-			$table_used_in_from[$table1] = true;
2329
-			foreach ($rightsidearray as $tablearray){
2330
-				$table2 = $tablearray['foreignTable']; // get foreign table
2331
-				$tableAlias = $aliases[$table2]; // get a list of aliases for this table
2332
-				foreach ($tableAlias as $table2) {
2333
-					//choose first alias that does not match
2334
-					// we are doing this because of self joins.
2335
-					// in case of self joins, the same table will have many aliases.
2336
-					if ($table2 != $table1) break;
2337
-				}
2338
-
2339
-				$col = $tablearray['foreingColumn'];
2340
-				$name = $tablearray['localColumn'];
2341
-				$from .= " LEFT JOIN $table on ($table1.$name = $table2.$col)";
2342
-				$table_used_in_from[$table2] = true;
2343
-			}
2344
-			$separator = ",";
2345
-		}
2346
-
2347
-		return "SELECT $select FROM $from WHERE $where";
2348
-	}
2349
-
2350
-	/**
2351
-	 * Generates SQL for create index statement for a bean.
2352
-	 *
2353
-	 * @param  SugarBean $bean SugarBean instance
2354
-	 * @param  array  $fields fields used in the index
2355
-	 * @param  string $name index name
2356
-	 * @param  bool   $unique Optional, set to true if this is an unique index
2357
-	 * @return string SQL Select Statement
2358
-	 */
2359
-	public function createIndexSQL(SugarBean $bean, array $fields, $name, $unique = true)
2360
-	{
2361
-		$unique = ($unique) ? "unique" : "";
2362
-		$tablename = $bean->getTableName();
2363
-		$columns = array();
2364
-		// get column names
2365
-		foreach ($fields as $fieldDef)
2366
-			$columns[] = $fieldDef['name'];
2367
-
2368
-		if (empty($columns))
2369
-			return "";
2370
-
2371
-		$columns = implode(",", $columns);
2372
-
2373
-		return "CREATE $unique INDEX $name ON $tablename ($columns)";
2374
-	}
2375
-
2376
-	/**
2377
-	 * Returns the type of the variable in the field
2378
-	 *
2379
-	 * @param  array $fieldDef Vardef-format field def
2380
-	 * @return string
2381
-	 */
2382
-	public function getFieldType($fieldDef)
2383
-	{
2384
-		// get the type for db type. if that is not set,
2385
-		// get it from type. This is done so that
2386
-		// we do not have change a lot of existing code
2387
-		// and add dbtype where type is being used for some special
2388
-		// purposes like referring to foreign table etc.
2389
-		if(!empty($fieldDef['dbType']))
2390
-			return  $fieldDef['dbType'];
2391
-		if(!empty($fieldDef['dbtype']))
2392
-			return  $fieldDef['dbtype'];
2393
-		if (!empty($fieldDef['type']))
2394
-			return  $fieldDef['type'];
2395
-		if (!empty($fieldDef['Type']))
2396
-			return  $fieldDef['Type'];
2397
-		if (!empty($fieldDef['data_type']))
2398
-			return  $fieldDef['data_type'];
2399
-
2400
-		return null;
2401
-	}
2688
+    public function dropColumnSQL($tablename, $fieldDefs)
2689
+    {
2690
+        return $this->changeColumnSQL($tablename, $fieldDefs, 'drop');
2691
+    }
2402 2692
 
2403 2693
     /**
2404
-     * retrieves the different components from the passed column type as it is used in the type mapping and vardefs
2405
-     * type format: <baseType>[(<len>[,<scale>])]
2406
-     * @param string $type Column type
2407
-     * @return array|bool array containing the different components of the passed in type or false in case the type contains illegal characters
2694
+     * Return a version of $proposed that can be used as a column name in any of our supported databases
2695
+     * Practically this means no longer than 25 characters as the smallest identifier length for our supported DBs is 30 chars for Oracle plus we add on at least four characters in some places (for indicies for example)
2696
+     * @param string|array $name Proposed name for the column
2697
+     * @param bool|string $ensureUnique Ensure the name is unique
2698
+     * @param string $type Name type (table, column)
2699
+     * @param bool $force Force new name
2700
+     * @return string|array Valid column name trimmed to right length and with invalid characters removed
2408 2701
      */
2409
-    public function getTypeParts($type)
2702
+    public function getValidDBName($name, $ensureUnique = false, $type = 'column', $force = false)
2410 2703
     {
2411
-        if(preg_match("#(?P<type>\w+)\s*(?P<arg>\((?P<len>\w+)\s*(,\s*(?P<scale>\d+))*\))*#", $type, $matches))
2412
-        {
2413
-            $return = array();  // Not returning matches array as such as we don't want to expose the regex make up on the interface
2414
-            $return['baseType'] = $matches['type'];
2415
-            if( isset($matches['arg'])) {
2416
-                $return['arg'] = $matches['arg'];
2704
+        if(is_array($name)) {
2705
+            $result = array();
2706
+            foreach($name as $field) {
2707
+                $result[] = $this->getValidDBName($field, $ensureUnique, $type);
2417 2708
             }
2418
-            if( isset($matches['len'])) {
2419
-                $return['len'] = $matches['len'];
2709
+            return $result;
2710
+        } else {
2711
+            if(strchr($name, ".")) {
2712
+                // this is a compound name with dots, handle separately
2713
+                $parts = explode(".", $name);
2714
+                if(count($parts) > 2) {
2715
+                    // some weird name, cut to table.name
2716
+                    array_splice($parts, 0, count($parts)-2);
2717
+                }
2718
+                $parts = $this->getValidDBName($parts, $ensureUnique, $type, $force);
2719
+                return join(".", $parts);
2420 2720
             }
2421
-            if( isset($matches['scale'])) {
2422
-                $return['scale'] = $matches['scale'];
2721
+            // first strip any invalid characters - all but word chars (which is alphanumeric and _)
2722
+            $name = preg_replace( '/[^\w]+/i', '', $name ) ;
2723
+            $len = strlen( $name ) ;
2724
+            $maxLen = empty($this->maxNameLengths[$type]) ? $this->maxNameLengths[$type]['column'] : $this->maxNameLengths[$type];
2725
+            if ($len <= $maxLen && !$force) {
2726
+                return strtolower($name);
2727
+            }
2728
+            if ($ensureUnique) {
2729
+                $md5str = md5($name);
2730
+                $tail = substr ( $name, -11) ;
2731
+                $temp = substr($md5str , strlen($md5str)-4 );
2732
+                $result = substr( $name, 0, 10) . $temp . $tail ;
2733
+            } else {
2734
+                $result = substr( $name, 0, 11) . substr( $name, 11 - $maxLen);
2423 2735
             }
2424
-            return $return;
2425
-        } else {
2426
-            return false;
2427
-        }
2428
-    }
2429
-
2430
-	/**
2431
-	 * Returns the defintion for a single column
2432
-	 *
2433
-	 * @param  array  $fieldDef Vardef-format field def
2434
-	 * @param  bool   $ignoreRequired  Optional, true if we should ignore this being a required field
2435
-	 * @param  string $table           Optional, table name
2436
-	 * @param  bool   $return_as_array Optional, true if we should return the result as an array instead of sql
2437
-	 * @return string or array if $return_as_array is true
2438
-	 */
2439
-	protected function oneColumnSQLRep($fieldDef, $ignoreRequired = false, $table = '', $return_as_array = false)
2440
-	{
2441
-		$name = $fieldDef['name'];
2442
-		$type = $this->getFieldType($fieldDef);
2443
-        $colType = $this->getColumnType($type);
2444 2736
 
2445
-        if($parts = $this->getTypeParts($colType))
2446
-        {
2447
-            $colBaseType = $parts['baseType'];
2448
-            $defLen =  isset($parts['len']) ? $parts['len'] : '255'; // Use the mappings length (precision) as default if it exists
2737
+            return strtolower( $result ) ;
2449 2738
         }
2739
+    }
2450 2740
 
2451
-        if(!empty($fieldDef['len'])) {
2452
-            if (in_array($colBaseType, array( 'nvarchar', 'nchar', 'varchar', 'varchar2', 'char',
2453
-                                          'clob', 'blob', 'text'))) {
2454
-          	    $colType = "$colBaseType(${fieldDef['len']})";
2455
-            } elseif(($colBaseType == 'decimal' || $colBaseType == 'float')){
2456
-                  if(!empty($fieldDef['precision']) && is_numeric($fieldDef['precision']))
2457
-                      if(strpos($fieldDef['len'],',') === false){
2458
-                          $colType = $colBaseType . "(".$fieldDef['len'].",".$fieldDef['precision'].")";
2459
-                      }else{
2460
-                          $colType = $colBaseType . "(".$fieldDef['len'].")";
2461
-                      }
2462
-                  else
2463
-                          $colType = $colBaseType . "(".$fieldDef['len'].")";
2464
-              }
2465
-        } else {
2466
-            if (in_array($colBaseType, array( 'nvarchar', 'nchar', 'varchar', 'varchar2', 'char'))) {
2467
-                $colType = "$colBaseType($defLen)";
2468
-            }
2469
-        }
2741
+    /**
2742
+     * Returns the valid type for a column given the type in fieldDef
2743
+     *
2744
+     * @param  string $type field type
2745
+     * @return string valid type for the given field
2746
+     */
2747
+    public function getColumnType($type)
2748
+    {
2749
+        return isset($this->type_map[$type])?$this->type_map[$type]:$type;
2750
+    }
2470 2751
 
2471
-        $default = '';
2752
+    /**
2753
+     * Checks to see if passed array is truely an array of defitions
2754
+     *
2755
+     * Such an array may have type as a key but it will point to an array
2756
+     * for a true array of definitions an to a col type for a definition only
2757
+     *
2758
+     * @param  mixed $defArray
2759
+     * @return bool
2760
+     */
2761
+    public function isFieldArray($defArray)
2762
+    {
2763
+        if ( !is_array($defArray) )
2764
+            return false;
2472 2765
 
2473
-        // Bug #52610 We should have ability don't add DEFAULT part to query for boolean fields
2474
-        if (!empty($fieldDef['no_default']))
2475
-        {
2476
-            // nothing to do
2477
-        }
2478
-        elseif (isset($fieldDef['default']) && strlen($fieldDef['default']) > 0)
2479
-        {
2480
-            $default = " DEFAULT ".$this->quoted($fieldDef['default']);
2481
-        }
2482
-        elseif (!isset($default) && $type == 'bool')
2483
-        {
2484
-            $default = " DEFAULT 0 ";
2766
+        if ( isset($defArray['type']) ){
2767
+            // type key exists. May be an array of defs or a simple definition
2768
+            return is_array($defArray['type']); // type is not an array => definition else array
2485 2769
         }
2486 2770
 
2487
-		$auto_increment = '';
2488
-		if(!empty($fieldDef['auto_increment']) && $fieldDef['auto_increment'])
2489
-			$auto_increment = $this->setAutoIncrement($table , $fieldDef['name']);
2490
-
2491
-		$required = 'NULL';  // MySQL defaults to NULL, SQL Server defaults to NOT NULL -- must specify
2492
-		//Starting in 6.0, only ID and auto_increment fields will be NOT NULL in the DB.
2493
-		if ((empty($fieldDef['isnull']) || strtolower($fieldDef['isnull']) == 'false') &&
2494
-			(!empty($auto_increment) || $name == 'id' || ($fieldDef['type'] == 'id' && !empty($fieldDef['required'])))) {
2495
-			$required =  "NOT NULL";
2496
-		}
2497
-		// If the field is marked both required & isnull=>false - alwqys make it not null
2498
-		// Use this to ensure primary key fields never defined as null
2499
-		if(isset($fieldDef['isnull']) && (strtolower($fieldDef['isnull']) == 'false' || $fieldDef['isnull'] === false)
2500
-			&& !empty($fieldDef['required'])) {
2501
-			$required =  "NOT NULL";
2502
-		}
2503
-		if ($ignoreRequired)
2504
-			$required = "";
2505
-
2506
-		if ( $return_as_array ) {
2507
-			return array(
2508
-				'name' => $name,
2509
-				'colType' => $colType,
2510
-                'colBaseType' => $colBaseType,  // Adding base type for easier processing in derived classes
2511
-				'default' => $default,
2512
-				'required' => $required,
2513
-				'auto_increment' => $auto_increment,
2514
-				'full' => "$name $colType $default $required $auto_increment",
2515
-				);
2516
-		} else {
2517
-			return "$name $colType $default $required $auto_increment";
2518
-		}
2519
-	}
2520
-
2521
-	/**
2522
-	 * Returns SQL defintions for all columns in a table
2523
-	 *
2524
-	 * @param  array  $fieldDefs  Vardef-format field def
2525
-	 * @param  bool   $ignoreRequired Optional, true if we should ignor this being a required field
2526
-	 * @param  string $tablename      Optional, table name
2527
-	 * @return string SQL column definitions
2528
-	 */
2529
-	protected function columnSQLRep($fieldDefs, $ignoreRequired = false, $tablename)
2530
-	{
2531
-		$columns = array();
2532
-
2533
-		if ($this->isFieldArray($fieldDefs)) {
2534
-			foreach ($fieldDefs as $fieldDef) {
2535
-				if(!isset($fieldDef['source']) || $fieldDef['source'] == 'db') {
2536
-					$columns[] = $this->oneColumnSQLRep($fieldDef,false, $tablename);
2537
-				}
2538
-			}
2539
-			$columns = implode(",", $columns);
2540
-		}
2541
-		else {
2542
-			$columns = $this->oneColumnSQLRep($fieldDefs,$ignoreRequired, $tablename);
2543
-		}
2544
-
2545
-		return $columns;
2546
-	}
2547
-
2548
-	/**
2549
-	 * Returns the next value for an auto increment
2550
-	 * @abstract
2551
-	 * @param  string $table Table name
2552
-	 * @param  string $field_name Field name
2553
-	 * @return string
2554
-	 */
2555
-	public function getAutoIncrement($table, $field_name)
2556
-	{
2557
-		return "";
2558
-	}
2559
-
2560
-	/**
2561
-	 * Returns the sql for the next value in a sequence
2562
-	 * @abstract
2563
-	 * @param  string $table  Table name
2564
-	 * @param  string $field_name  Field name
2565
-	 * @return string
2566
-	 */
2567
-	public function getAutoIncrementSQL($table, $field_name)
2568
-	{
2569
-		return "";
2570
-	}
2571
-
2572
-	/**
2573
-	 * Either creates an auto increment through queries or returns sql for auto increment
2574
-	 * that can be appended to the end of column defination (mysql)
2575
-	 * @abstract
2576
-	 * @param  string $table Table name
2577
-	 * @param  string $field_name Field name
2578
-	 * @return string
2579
-	 */
2580
-	protected function setAutoIncrement($table, $field_name)
2581
-	{
2582
-		$this->deleteAutoIncrement($table, $field_name);
2583
-		return "";
2584
-	}
2771
+        // type does not exist. Must be array of definitions
2772
+        return true;
2773
+    }
2585 2774
 
2586 2775
     /**
2587
-     * Sets the next auto-increment value of a column to a specific value.
2588
-     * @abstract
2589
-     * @param  string $table Table name
2590
-     * @param  string $field_name Field name
2591
-     * @param  int $start_value  Starting autoincrement value
2592
-     * @return string
2776
+     * returns true if the type can be mapped to a valid column type
2593 2777
      *
2778
+     * @param  string $type
2779
+     * @return bool
2594 2780
      */
2595
-	public function setAutoIncrementStart($table, $field_name, $start_value)
2596
-	{
2597
-		return "";
2598
-	}
2599
-
2600
-	/**
2601
-	 * Deletes an auto increment
2602
-	 * @abstract
2603
-	 * @param string $table tablename
2604
-	 * @param string $field_name
2605
-	 */
2606
-	public function deleteAutoIncrement($table, $field_name)
2607
-	{
2608
-		return;
2609
-	}
2610
-
2611
-	/**
2612
-	 * This method generates sql for adding a column to table identified by field def.
2613
-	 *
2614
-	 * @param  string $tablename
2615
-	 * @param  array  $fieldDefs
2616
-	 * @return string SQL statement
2617
-	 */
2618
-	public function addColumnSQL($tablename, $fieldDefs)
2619
-	{
2620
-	    return $this->changeColumnSQL($tablename, $fieldDefs, 'add');
2621
-	}
2622
-
2623
-	/**
2624
-	 * This method genrates sql for altering old column identified by oldFieldDef to new fieldDef.
2625
-	 *
2626
-	 * @param  string $tablename
2627
-	 * @param  array  $newFieldDefs
2628
-	 * @param  bool  $ignorerequired Optional, true if we should ignor this being a required field
2629
-	 * @return string|array SQL statement(s)
2630
-	 */
2631
-	public function alterColumnSQL($tablename, $newFieldDefs, $ignorerequired = false)
2632
-	{
2633
-		return $this->changeColumnSQL($tablename, $newFieldDefs, 'modify', $ignorerequired);
2634
-	}
2635
-
2636
-	/**
2637
-	 * Generates SQL for dropping a table.
2638
-	 *
2639
-	 * @param  SugarBean $bean Sugarbean instance
2640
-	 * @return string SQL statement
2641
-	 */
2642
-	public function dropTableSQL(SugarBean $bean)
2643
-	{
2644
-		return $this->dropTableNameSQL($bean->getTableName());
2645
-	}
2646
-
2647
-	/**
2648
-	 * Generates SQL for dropping a table.
2649
-	 *
2650
-	 * @param  string $name table name
2651
-	 * @return string SQL statement
2652
-	 */
2653
-	public function dropTableNameSQL($name)
2654
-	{
2655
-		return "DROP TABLE ".$name;
2656
-	}
2657
-
2658
-	/**
2659
-	 * Generates SQL for truncating a table.
2660
-	 * @param  string $name  table name
2661
-	 * @return string
2662
-	 */
2663
-	public function truncateTableSQL($name)
2664
-	{
2665
-		return "TRUNCATE $name";
2666
-	}
2667
-
2668
-	/**
2669
-	 * This method generates sql that deletes a column identified by fieldDef.
2670
-	 *
2671
-	 * @param  SugarBean $bean      Sugarbean instance
2672
-	 * @param  array  $fieldDefs
2673
-	 * @return string SQL statement
2674
-	 */
2675
-	public function deleteColumnSQL(SugarBean $bean, $fieldDefs)
2676
-	{
2677
-		return $this->dropColumnSQL($bean->getTableName(), $fieldDefs);
2678
-	}
2679
-
2680
-	/**
2681
-	 * This method generates sql that drops a column identified by fieldDef.
2682
-	 * Designed to work like the other addColumnSQL() and alterColumnSQL() functions
2683
-	 *
2684
-	 * @param  string $tablename
2685
-	 * @param  array  $fieldDefs
2686
-	 * @return string SQL statement
2687
-	 */
2688
-	public function dropColumnSQL($tablename, $fieldDefs)
2689
-	{
2690
-		return $this->changeColumnSQL($tablename, $fieldDefs, 'drop');
2691
-	}
2781
+    protected function validColumnType($type)
2782
+    {
2783
+        $type = $this->getColumnType($type);
2784
+        return !empty($type);
2785
+    }
2692 2786
 
2693 2787
     /**
2694
-     * Return a version of $proposed that can be used as a column name in any of our supported databases
2695
-     * Practically this means no longer than 25 characters as the smallest identifier length for our supported DBs is 30 chars for Oracle plus we add on at least four characters in some places (for indicies for example)
2696
-     * @param string|array $name Proposed name for the column
2697
-     * @param bool|string $ensureUnique Ensure the name is unique
2698
-     * @param string $type Name type (table, column)
2699
-     * @param bool $force Force new name
2700
-     * @return string|array Valid column name trimmed to right length and with invalid characters removed
2701
-     */
2702
-	public function getValidDBName($name, $ensureUnique = false, $type = 'column', $force = false)
2703
-	{
2704
-		if(is_array($name)) {
2705
-			$result = array();
2706
-			foreach($name as $field) {
2707
-				$result[] = $this->getValidDBName($field, $ensureUnique, $type);
2708
-			}
2709
-			return $result;
2710
-		} else {
2711
-		    if(strchr($name, ".")) {
2712
-		        // this is a compound name with dots, handle separately
2713
-		        $parts = explode(".", $name);
2714
-		        if(count($parts) > 2) {
2715
-		            // some weird name, cut to table.name
2716
-		            array_splice($parts, 0, count($parts)-2);
2717
-		        }
2718
-		        $parts = $this->getValidDBName($parts, $ensureUnique, $type, $force);
2719
-                return join(".", $parts);
2720
-		    }
2721
-			// first strip any invalid characters - all but word chars (which is alphanumeric and _)
2722
-			$name = preg_replace( '/[^\w]+/i', '', $name ) ;
2723
-			$len = strlen( $name ) ;
2724
-			$maxLen = empty($this->maxNameLengths[$type]) ? $this->maxNameLengths[$type]['column'] : $this->maxNameLengths[$type];
2725
-			if ($len <= $maxLen && !$force) {
2726
-				return strtolower($name);
2727
-			}
2728
-			if ($ensureUnique) {
2729
-				$md5str = md5($name);
2730
-				$tail = substr ( $name, -11) ;
2731
-				$temp = substr($md5str , strlen($md5str)-4 );
2732
-				$result = substr( $name, 0, 10) . $temp . $tail ;
2733
-			} else {
2734
-				$result = substr( $name, 0, 11) . substr( $name, 11 - $maxLen);
2735
-			}
2736
-
2737
-			return strtolower( $result ) ;
2738
-		}
2739
-	}
2740
-
2741
-	/**
2742
-	 * Returns the valid type for a column given the type in fieldDef
2743
-	 *
2744
-	 * @param  string $type field type
2745
-	 * @return string valid type for the given field
2746
-	 */
2747
-	public function getColumnType($type)
2748
-	{
2749
-		return isset($this->type_map[$type])?$this->type_map[$type]:$type;
2750
-	}
2751
-
2752
-	/**
2753
-	 * Checks to see if passed array is truely an array of defitions
2754
-	 *
2755
-	 * Such an array may have type as a key but it will point to an array
2756
-	 * for a true array of definitions an to a col type for a definition only
2757
-	 *
2758
-	 * @param  mixed $defArray
2759
-	 * @return bool
2760
-	 */
2761
-	public function isFieldArray($defArray)
2762
-	{
2763
-		if ( !is_array($defArray) )
2764
-			return false;
2765
-
2766
-		if ( isset($defArray['type']) ){
2767
-			// type key exists. May be an array of defs or a simple definition
2768
-			return is_array($defArray['type']); // type is not an array => definition else array
2769
-		}
2770
-
2771
-		// type does not exist. Must be array of definitions
2772
-		return true;
2773
-	}
2774
-
2775
-	/**
2776
-	 * returns true if the type can be mapped to a valid column type
2777
-	 *
2778
-	 * @param  string $type
2779
-	 * @return bool
2780
-	 */
2781
-	protected function validColumnType($type)
2782
-	{
2783
-		$type = $this->getColumnType($type);
2784
-		return !empty($type);
2785
-	}
2786
-
2787
-	/**
2788
-	 * Generate query for audit table
2789
-	 * @param SugarBean $bean SugarBean that was changed
2790
-	 * @param array $changes List of changes, contains 'before' and 'after'
2788
+     * Generate query for audit table
2789
+     * @param SugarBean $bean SugarBean that was changed
2790
+     * @param array $changes List of changes, contains 'before' and 'after'
2791 2791
      * @return string  Audit table INSERT query
2792 2792
      */
2793
-	protected function auditSQL(SugarBean $bean, $changes)
2794
-	{
2795
-		global $current_user;
2796
-		$sql = "INSERT INTO ".$bean->get_audit_table_name();
2797
-		//get field defs for the audit table.
2798
-		require('metadata/audit_templateMetaData.php');
2799
-		$fieldDefs = $dictionary['audit']['fields'];
2800
-
2801
-		$values=array();
2802
-		$values['id'] = $this->massageValue(create_guid(), $fieldDefs['id']);
2803
-		$values['parent_id']= $this->massageValue($bean->id, $fieldDefs['parent_id']);
2804
-		$values['field_name']= $this->massageValue($changes['field_name'], $fieldDefs['field_name']);
2805
-		$values['data_type'] = $this->massageValue($changes['data_type'], $fieldDefs['data_type']);
2806
-		if ($changes['data_type']=='text') {
2807
-			$values['before_value_text'] = $this->massageValue($changes['before'], $fieldDefs['before_value_text']);
2808
-			$values['after_value_text'] = $this->massageValue($changes['after'], $fieldDefs['after_value_text']);
2809
-		} else {
2810
-			$values['before_value_string'] = $this->massageValue($changes['before'], $fieldDefs['before_value_string']);
2811
-			$values['after_value_string'] = $this->massageValue($changes['after'], $fieldDefs['after_value_string']);
2812
-		}
2813
-		$values['date_created'] = $this->massageValue(TimeDate::getInstance()->nowDb(), $fieldDefs['date_created'] );
2814
-		$values['created_by'] = $this->massageValue($current_user->id, $fieldDefs['created_by']);
2815
-
2816
-		$sql .= "(".implode(",", array_keys($values)).") ";
2817
-		$sql .= "VALUES(".implode(",", $values).")";
2818
-		return $sql;
2819
-	}
2793
+    protected function auditSQL(SugarBean $bean, $changes)
2794
+    {
2795
+        global $current_user;
2796
+        $sql = "INSERT INTO ".$bean->get_audit_table_name();
2797
+        //get field defs for the audit table.
2798
+        require('metadata/audit_templateMetaData.php');
2799
+        $fieldDefs = $dictionary['audit']['fields'];
2800
+
2801
+        $values=array();
2802
+        $values['id'] = $this->massageValue(create_guid(), $fieldDefs['id']);
2803
+        $values['parent_id']= $this->massageValue($bean->id, $fieldDefs['parent_id']);
2804
+        $values['field_name']= $this->massageValue($changes['field_name'], $fieldDefs['field_name']);
2805
+        $values['data_type'] = $this->massageValue($changes['data_type'], $fieldDefs['data_type']);
2806
+        if ($changes['data_type']=='text') {
2807
+            $values['before_value_text'] = $this->massageValue($changes['before'], $fieldDefs['before_value_text']);
2808
+            $values['after_value_text'] = $this->massageValue($changes['after'], $fieldDefs['after_value_text']);
2809
+        } else {
2810
+            $values['before_value_string'] = $this->massageValue($changes['before'], $fieldDefs['before_value_string']);
2811
+            $values['after_value_string'] = $this->massageValue($changes['after'], $fieldDefs['after_value_string']);
2812
+        }
2813
+        $values['date_created'] = $this->massageValue(TimeDate::getInstance()->nowDb(), $fieldDefs['date_created'] );
2814
+        $values['created_by'] = $this->massageValue($current_user->id, $fieldDefs['created_by']);
2815
+
2816
+        $sql .= "(".implode(",", array_keys($values)).") ";
2817
+        $sql .= "VALUES(".implode(",", $values).")";
2818
+        return $sql;
2819
+    }
2820 2820
 
2821 2821
     /**
2822 2822
      * Saves changes to module's audit table
@@ -2826,10 +2826,10 @@  discard block
 block discarded – undo
2826 2826
      * @return bool query result
2827 2827
      *
2828 2828
      */
2829
-	public function save_audit_records(SugarBean $bean, $changes)
2830
-	{
2831
-		return $this->query($this->auditSQL($bean, $changes));
2832
-	}
2829
+    public function save_audit_records(SugarBean $bean, $changes)
2830
+    {
2831
+        return $this->query($this->auditSQL($bean, $changes));
2832
+    }
2833 2833
 
2834 2834
     /**
2835 2835
      * Finds fields whose value has changed.
@@ -2841,7 +2841,7 @@  discard block
 block discarded – undo
2841 2841
      * @return array
2842 2842
      */
2843 2843
     public function getDataChanges(SugarBean &$bean, array $field_filter = null)
2844
-	{
2844
+    {
2845 2845
         $changed_values=array();
2846 2846
 
2847 2847
         $fetched_row = array();
@@ -2918,10 +2918,10 @@  discard block
 block discarded – undo
2918 2918
                         }
2919 2919
                     }
2920 2920
                 }
2921
-			}
2922
-		}
2923
-		return $changed_values;
2924
-	}
2921
+            }
2922
+        }
2923
+        return $changed_values;
2924
+    }
2925 2925
 
2926 2926
     /**
2927 2927
      * Uses the audit enabled fields array to find fields whose value has changed.
@@ -2937,40 +2937,40 @@  discard block
 block discarded – undo
2937 2937
         return $this->getDataChanges($bean, array_keys($audit_fields));
2938 2938
     }
2939 2939
 
2940
-	/**
2941
-	 * Setup FT indexing
2942
-	 * @abstract
2943
-	 */
2944
-	public function full_text_indexing_setup()
2945
-	{
2946
-		// Most DBs have nothing to setup, so provide default empty function
2947
-	}
2948
-
2949
-	/**
2950
-	 * Quotes a string for storing in the database
2951
-	 * @deprecated
2952
-	 * Return value will be not surrounded by quotes
2953
-	 *
2954
-	 * @param  string $string
2955
-	 * @return string
2956
-	 */
2957
-	public function escape_quote($string)
2958
-	{
2959
-		return $this->quote($string);
2960
-	}
2961
-
2962
-	/**
2963
-	 * Quotes a string for storing in the database
2964
-	 * @deprecated
2965
-	 * Return value will be not surrounded by quotes
2966
-	 *
2967
-	 * @param  string $string
2968
-	 * @return string
2969
-	 */
2970
-	public function quoteFormEmail($string)
2971
-	{
2972
-		return $this->quote($string);
2973
-	}
2940
+    /**
2941
+     * Setup FT indexing
2942
+     * @abstract
2943
+     */
2944
+    public function full_text_indexing_setup()
2945
+    {
2946
+        // Most DBs have nothing to setup, so provide default empty function
2947
+    }
2948
+
2949
+    /**
2950
+     * Quotes a string for storing in the database
2951
+     * @deprecated
2952
+     * Return value will be not surrounded by quotes
2953
+     *
2954
+     * @param  string $string
2955
+     * @return string
2956
+     */
2957
+    public function escape_quote($string)
2958
+    {
2959
+        return $this->quote($string);
2960
+    }
2961
+
2962
+    /**
2963
+     * Quotes a string for storing in the database
2964
+     * @deprecated
2965
+     * Return value will be not surrounded by quotes
2966
+     *
2967
+     * @param  string $string
2968
+     * @return string
2969
+     */
2970
+    public function quoteFormEmail($string)
2971
+    {
2972
+        return $this->quote($string);
2973
+    }
2974 2974
 
2975 2975
     /**
2976 2976
      * Renames an index using fields definition
@@ -2980,49 +2980,49 @@  discard block
 block discarded – undo
2980 2980
      * @param  string $table_name
2981 2981
      * @return string SQL statement
2982 2982
      */
2983
-	public function renameIndexDefs($old_definition, $new_definition, $table_name)
2984
-	{
2985
-		return array($this->add_drop_constraint($table_name,$old_definition,true),
2986
-				$this->add_drop_constraint($table_name,$new_definition), false);
2987
-	}
2983
+    public function renameIndexDefs($old_definition, $new_definition, $table_name)
2984
+    {
2985
+        return array($this->add_drop_constraint($table_name,$old_definition,true),
2986
+                $this->add_drop_constraint($table_name,$new_definition), false);
2987
+    }
2988 2988
 
2989
-	/**
2990
-	 * Check if type is boolean
2991
-	 * @param string $type
2989
+    /**
2990
+     * Check if type is boolean
2991
+     * @param string $type
2992 2992
      * @return bool
2993 2993
      */
2994
-	public function isBooleanType($type)
2995
-	{
2996
-		return 'bool' == $type;
2997
-	}
2994
+    public function isBooleanType($type)
2995
+    {
2996
+        return 'bool' == $type;
2997
+    }
2998 2998
 
2999
-	/**
3000
-	 * Get truth value for boolean type
3001
-	 * Allows 'off' to mean false, along with all 'empty' values
3002
-	 * @param mixed $val
2999
+    /**
3000
+     * Get truth value for boolean type
3001
+     * Allows 'off' to mean false, along with all 'empty' values
3002
+     * @param mixed $val
3003 3003
      * @return bool
3004
-	 */
3005
-	protected function _getBooleanValue($val)
3006
-	{
3007
-		//need to put the === sign here otherwise true == 'non empty string'
3008
-		if (empty($val) or $val==='off')
3009
-			return false;
3010
-
3011
-		return true;
3012
-	}
3013
-
3014
-	/**
3015
-	 * Check if type is a number
3016
-	 * @param string $type
3004
+     */
3005
+    protected function _getBooleanValue($val)
3006
+    {
3007
+        //need to put the === sign here otherwise true == 'non empty string'
3008
+        if (empty($val) or $val==='off')
3009
+            return false;
3010
+
3011
+        return true;
3012
+    }
3013
+
3014
+    /**
3015
+     * Check if type is a number
3016
+     * @param string $type
3017 3017
      * @return bool
3018
-	 */
3019
-	public function isNumericType($type)
3020
-	{
3021
-	    if(isset($this->type_class[$type]) && ($this->type_class[$type] == 'int' || $this->type_class[$type] == 'float')) {
3022
-	        return true;
3023
-	    }
3024
-		return false;
3025
-	}
3018
+     */
3019
+    public function isNumericType($type)
3020
+    {
3021
+        if(isset($this->type_class[$type]) && ($this->type_class[$type] == 'int' || $this->type_class[$type] == 'float')) {
3022
+            return true;
3023
+        }
3024
+        return false;
3025
+    }
3026 3026
 
3027 3027
     /**
3028 3028
      * Check if the value is empty value for this type
@@ -3030,272 +3030,272 @@  discard block
 block discarded – undo
3030 3030
      * @param string $type Type (one of vardef types)
3031 3031
      * @return bool true if the value if empty
3032 3032
      */
3033
-	protected function _emptyValue($val, $type)
3034
-	{
3035
-		if (empty($val))
3036
-			return true;
3037
-
3038
-		if($this->emptyValue($type) == $val) {
3039
-			return true;
3040
-		}
3041
-		switch ($type) {
3042
-			case 'decimal':
3043
-			case 'decimal2':
3044
-			case 'int':
3045
-			case 'double':
3046
-			case 'float':
3047
-			case 'uint':
3048
-			case 'ulong':
3049
-			case 'long':
3050
-			case 'short':
3051
-				return ($val == 0);
3052
-			case 'date':
3053
-				if ($val == '0000-00-00')
3054
-					return true;
3055
-				if ($val == 'NULL')
3056
-					return true;
3057
-				return false;
3058
-		}
3059
-
3060
-		return false;
3061
-	}
3062
-
3063
-	/**
3033
+    protected function _emptyValue($val, $type)
3034
+    {
3035
+        if (empty($val))
3036
+            return true;
3037
+
3038
+        if($this->emptyValue($type) == $val) {
3039
+            return true;
3040
+        }
3041
+        switch ($type) {
3042
+            case 'decimal':
3043
+            case 'decimal2':
3044
+            case 'int':
3045
+            case 'double':
3046
+            case 'float':
3047
+            case 'uint':
3048
+            case 'ulong':
3049
+            case 'long':
3050
+            case 'short':
3051
+                return ($val == 0);
3052
+            case 'date':
3053
+                if ($val == '0000-00-00')
3054
+                    return true;
3055
+                if ($val == 'NULL')
3056
+                    return true;
3057
+                return false;
3058
+        }
3059
+
3060
+        return false;
3061
+    }
3062
+
3063
+    /**
3064 3064
      * @abstract
3065
-	 * Does this type represent text (i.e., non-varchar) value?
3066
-	 * @param string $type
3065
+     * Does this type represent text (i.e., non-varchar) value?
3066
+     * @param string $type
3067 3067
      * @return bool
3068
-	 */
3069
-	public function isTextType($type)
3070
-	{
3071
-		return false;
3072
-	}
3073
-
3074
-	/**
3075
-	 * Check if this DB supports certain capability
3076
-	 * See $this->capabilities for the list
3077
-	 * @param string $cap
3068
+     */
3069
+    public function isTextType($type)
3070
+    {
3071
+        return false;
3072
+    }
3073
+
3074
+    /**
3075
+     * Check if this DB supports certain capability
3076
+     * See $this->capabilities for the list
3077
+     * @param string $cap
3078 3078
      * @return bool
3079
-	 */
3080
-	public function supports($cap)
3081
-	{
3082
-		return !empty($this->capabilities[$cap]);
3083
-	}
3084
-
3085
-	/**
3086
-	 * Create ORDER BY clause for ENUM type field
3087
-	 * @param string $order_by Field name
3088
-	 * @param array $values Possible enum value
3089
-	 * @param string $order_dir Order direction, ASC or DESC
3079
+     */
3080
+    public function supports($cap)
3081
+    {
3082
+        return !empty($this->capabilities[$cap]);
3083
+    }
3084
+
3085
+    /**
3086
+     * Create ORDER BY clause for ENUM type field
3087
+     * @param string $order_by Field name
3088
+     * @param array $values Possible enum value
3089
+     * @param string $order_dir Order direction, ASC or DESC
3090 3090
      * @return string
3091 3091
      */
3092
-	public function orderByEnum($order_by, $values, $order_dir)
3093
-	{
3094
-		$i = 0;
3095
-		$order_by_arr = array();
3096
-		foreach ($values as $key => $value) {
3097
-			if($key == '') {
3098
-				$order_by_arr[] = "WHEN ($order_by='' OR $order_by IS NULL) THEN $i";
3099
-			} else {
3100
-				$order_by_arr[] = "WHEN $order_by=".$this->quoted($key)." THEN $i";
3101
-			}
3102
-			$i++;
3103
-		}
3104
-		return "CASE ".implode("\n", $order_by_arr)." ELSE $i END $order_dir\n";
3105
-	}
3106
-
3107
-	/**
3108
-	 * Return representation of an empty value depending on type
3109
-	 * The value is fully quoted, converted, etc.
3110
-	 * @param string $type
3092
+    public function orderByEnum($order_by, $values, $order_dir)
3093
+    {
3094
+        $i = 0;
3095
+        $order_by_arr = array();
3096
+        foreach ($values as $key => $value) {
3097
+            if($key == '') {
3098
+                $order_by_arr[] = "WHEN ($order_by='' OR $order_by IS NULL) THEN $i";
3099
+            } else {
3100
+                $order_by_arr[] = "WHEN $order_by=".$this->quoted($key)." THEN $i";
3101
+            }
3102
+            $i++;
3103
+        }
3104
+        return "CASE ".implode("\n", $order_by_arr)." ELSE $i END $order_dir\n";
3105
+    }
3106
+
3107
+    /**
3108
+     * Return representation of an empty value depending on type
3109
+     * The value is fully quoted, converted, etc.
3110
+     * @param string $type
3111 3111
      * @return mixed Empty value
3112 3112
      */
3113
-	public function emptyValue($type)
3114
-	{
3115
-		if(isset($this->type_class[$type]) && ($this->type_class[$type] == 'bool' || $this->type_class[$type] == 'int' || $this->type_class[$type] == 'float')) {
3116
-			return 0;
3117
-		}
3113
+    public function emptyValue($type)
3114
+    {
3115
+        if(isset($this->type_class[$type]) && ($this->type_class[$type] == 'bool' || $this->type_class[$type] == 'int' || $this->type_class[$type] == 'float')) {
3116
+            return 0;
3117
+        }
3118 3118
 
3119
-		return "''";
3120
-	}
3119
+        return "''";
3120
+    }
3121 3121
 
3122
-	/**
3123
-	 * List of available collation settings
3122
+    /**
3123
+     * List of available collation settings
3124 3124
      * @abstract
3125
-	 * @return string
3126
-	 */
3127
-	public function getDefaultCollation()
3128
-	{
3129
-		return null;
3130
-	}
3131
-
3132
-	/**
3133
-	 * List of available collation settings
3125
+     * @return string
3126
+     */
3127
+    public function getDefaultCollation()
3128
+    {
3129
+        return null;
3130
+    }
3131
+
3132
+    /**
3133
+     * List of available collation settings
3134 3134
      * @abstract
3135
-	 * @return array
3136
-	 */
3137
-	public function getCollationList()
3138
-	{
3139
-		return null;
3140
-	}
3141
-
3142
-	/**
3143
-	 * Returns the number of columns in a table
3144
-	 *
3145
-	 * @param  string $table_name
3146
-	 * @return int
3147
-	 */
3148
-	public function number_of_columns($table_name)
3149
-	{
3150
-		$table = $this->getTableDescription($table_name);
3151
-		return count($table);
3152
-	}
3153
-
3154
-	/**
3155
-	 * Return limit query based on given query
3156
-	 * @param string $sql
3157
-	 * @param int $start
3158
-	 * @param int $count
3159
-	 * @param bool $dieOnError
3160
-	 * @param string $msg
3135
+     * @return array
3136
+     */
3137
+    public function getCollationList()
3138
+    {
3139
+        return null;
3140
+    }
3141
+
3142
+    /**
3143
+     * Returns the number of columns in a table
3144
+     *
3145
+     * @param  string $table_name
3146
+     * @return int
3147
+     */
3148
+    public function number_of_columns($table_name)
3149
+    {
3150
+        $table = $this->getTableDescription($table_name);
3151
+        return count($table);
3152
+    }
3153
+
3154
+    /**
3155
+     * Return limit query based on given query
3156
+     * @param string $sql
3157
+     * @param int $start
3158
+     * @param int $count
3159
+     * @param bool $dieOnError
3160
+     * @param string $msg
3161 3161
      * @return resource|bool query result
3162 3162
      * @see DBManager::limitQuery()
3163
-	 */
3164
-	public function limitQuerySql($sql, $start, $count, $dieOnError=false, $msg='')
3165
-	{
3166
-		return $this->limitQuery($sql,$start,$count,$dieOnError,$msg,false);
3167
-	}
3168
-
3169
-	/**
3170
-	 * Return current time in format fit for insertion into DB (with quotes)
3171
-	 * @return string
3172
-	 */
3173
-	public function now()
3174
-	{
3175
-		return $this->convert($this->quoted(TimeDate::getInstance()->nowDb()), "datetime");
3176
-	}
3177
-
3178
-	/**
3179
-	 * Check if connecting user has certain privilege
3180
-	 * @param string $privilege
3163
+     */
3164
+    public function limitQuerySql($sql, $start, $count, $dieOnError=false, $msg='')
3165
+    {
3166
+        return $this->limitQuery($sql,$start,$count,$dieOnError,$msg,false);
3167
+    }
3168
+
3169
+    /**
3170
+     * Return current time in format fit for insertion into DB (with quotes)
3171
+     * @return string
3172
+     */
3173
+    public function now()
3174
+    {
3175
+        return $this->convert($this->quoted(TimeDate::getInstance()->nowDb()), "datetime");
3176
+    }
3177
+
3178
+    /**
3179
+     * Check if connecting user has certain privilege
3180
+     * @param string $privilege
3181 3181
      * @return bool Privilege allowed?
3182 3182
      */
3183
-	public function checkPrivilege($privilege)
3184
-	{
3185
-		switch($privilege) {
3186
-			case "CREATE TABLE":
3187
-				$this->query("CREATE TABLE temp (id varchar(36))");
3188
-				break;
3189
-			case "DROP TABLE":
3190
-				$sql = $this->dropTableNameSQL("temp");
3191
-				$this->query($sql);
3192
-				break;
3193
-			case "INSERT":
3194
-				$this->query("INSERT INTO temp (id) VALUES ('abcdef0123456789abcdef0123456789abcd')");
3195
-				break;
3196
-			case "UPDATE":
3197
-				$this->query("UPDATE temp SET id = '100000000000000000000000000000000000' WHERE id = 'abcdef0123456789abcdef0123456789abcd'");
3198
-				break;
3199
-			case 'SELECT':
3200
-				return $this->getOne('SELECT id FROM temp WHERE id=\'100000000000000000000000000000000000\'', false);
3201
-			case 'DELETE':
3202
-				$this->query("DELETE FROM temp WHERE id = '100000000000000000000000000000000000'");
3203
-				break;
3204
-			case "ADD COLUMN":
3205
-				$test = array("test" => array("name" => "test", "type" => "varchar", "len" => 50));
3206
-				$sql = 	$this->changeColumnSQL("temp", $test, "add");
3207
-				$this->query($sql);
3208
-				break;
3209
-			case "CHANGE COLUMN":
3210
-				$test = array("test" => array("name" => "test", "type" => "varchar", "len" => 100));
3211
-				$sql = 	$this->changeColumnSQL("temp", $test, "modify");
3212
-				$this->query($sql);
3213
-				break;
3214
-			case "DROP COLUMN":
3215
-				$test = array("test" => array("name" => "test", "type" => "varchar", "len" => 100));
3216
-				$sql = 	$this->changeColumnSQL("temp", $test, "drop");
3217
-				$this->query($sql);
3218
-				break;
3219
-			default:
3220
-				return false;
3221
-		}
3222
-		if($this->checkError("Checking privileges")) {
3223
-			return false;
3224
-		}
3225
-		return true;
3226
-	}
3227
-
3228
-	/**
3229
-	 * Check if the query is a select query
3230
-	 * @param string $query
3183
+    public function checkPrivilege($privilege)
3184
+    {
3185
+        switch($privilege) {
3186
+            case "CREATE TABLE":
3187
+                $this->query("CREATE TABLE temp (id varchar(36))");
3188
+                break;
3189
+            case "DROP TABLE":
3190
+                $sql = $this->dropTableNameSQL("temp");
3191
+                $this->query($sql);
3192
+                break;
3193
+            case "INSERT":
3194
+                $this->query("INSERT INTO temp (id) VALUES ('abcdef0123456789abcdef0123456789abcd')");
3195
+                break;
3196
+            case "UPDATE":
3197
+                $this->query("UPDATE temp SET id = '100000000000000000000000000000000000' WHERE id = 'abcdef0123456789abcdef0123456789abcd'");
3198
+                break;
3199
+            case 'SELECT':
3200
+                return $this->getOne('SELECT id FROM temp WHERE id=\'100000000000000000000000000000000000\'', false);
3201
+            case 'DELETE':
3202
+                $this->query("DELETE FROM temp WHERE id = '100000000000000000000000000000000000'");
3203
+                break;
3204
+            case "ADD COLUMN":
3205
+                $test = array("test" => array("name" => "test", "type" => "varchar", "len" => 50));
3206
+                $sql = 	$this->changeColumnSQL("temp", $test, "add");
3207
+                $this->query($sql);
3208
+                break;
3209
+            case "CHANGE COLUMN":
3210
+                $test = array("test" => array("name" => "test", "type" => "varchar", "len" => 100));
3211
+                $sql = 	$this->changeColumnSQL("temp", $test, "modify");
3212
+                $this->query($sql);
3213
+                break;
3214
+            case "DROP COLUMN":
3215
+                $test = array("test" => array("name" => "test", "type" => "varchar", "len" => 100));
3216
+                $sql = 	$this->changeColumnSQL("temp", $test, "drop");
3217
+                $this->query($sql);
3218
+                break;
3219
+            default:
3220
+                return false;
3221
+        }
3222
+        if($this->checkError("Checking privileges")) {
3223
+            return false;
3224
+        }
3225
+        return true;
3226
+    }
3227
+
3228
+    /**
3229
+     * Check if the query is a select query
3230
+     * @param string $query
3231 3231
      * @return bool  Is query SELECT?
3232 3232
      */
3233
-	protected function isSelect($query)
3234
-	{
3235
-		$query = trim($query);
3236
-		$select_check = strpos(strtolower($query), strtolower("SELECT"));
3237
-		//Checks to see if there is union select which is valid
3238
-		$select_check2 = strpos(strtolower($query), strtolower("(SELECT"));
3239
-		if($select_check==0 || $select_check2==0){
3240
-			//Returning false means query is ok!
3241
-			return true;
3242
-		}
3243
-		return false;
3244
-	}
3245
-
3246
-	/**
3247
-	 * Parse fulltext search query with mysql syntax:
3248
-	 *  terms quoted by ""
3249
-	 *  + means the term must be included
3250
-	 *  - means the term must be excluded
3251
-	 *  * or % at the end means wildcard
3252
-	 * @param string $query
3253
-	 * @return array of 3 elements - query terms, mandatory terms and excluded terms
3254
-	 */
3255
-	public function parseFulltextQuery($query)
3256
-	{
3257
-		/* split on space or comma, double quotes with \ for escape */
3258
-		if(strpbrk($query, " ,")) {
3259
-			// ("([^"]*?)"|[^" ,]+)((, )+)?
3260
-			// '/([^" ,]+|".*?[^\\\\]")(,|\s)\s*/'
3261
-			if(!preg_match_all('/("([^"]*?)"|[^"\s,]+)((,\s)+)?/', $query, $m)) {
3262
-				return false;
3263
-			}
3264
-			$qterms = $m[1];
3265
-		} else {
3266
-			$qterms = array($query);
3267
-		}
3268
-		$terms = $must_terms = $not_terms = array();
3269
-		foreach($qterms as $item) {
3270
-			if($item[0] == '"') {
3271
-				$item = trim($item, '"');
3272
-			}
3273
-			if($item[0] == '+') {
3233
+    protected function isSelect($query)
3234
+    {
3235
+        $query = trim($query);
3236
+        $select_check = strpos(strtolower($query), strtolower("SELECT"));
3237
+        //Checks to see if there is union select which is valid
3238
+        $select_check2 = strpos(strtolower($query), strtolower("(SELECT"));
3239
+        if($select_check==0 || $select_check2==0){
3240
+            //Returning false means query is ok!
3241
+            return true;
3242
+        }
3243
+        return false;
3244
+    }
3245
+
3246
+    /**
3247
+     * Parse fulltext search query with mysql syntax:
3248
+     *  terms quoted by ""
3249
+     *  + means the term must be included
3250
+     *  - means the term must be excluded
3251
+     *  * or % at the end means wildcard
3252
+     * @param string $query
3253
+     * @return array of 3 elements - query terms, mandatory terms and excluded terms
3254
+     */
3255
+    public function parseFulltextQuery($query)
3256
+    {
3257
+        /* split on space or comma, double quotes with \ for escape */
3258
+        if(strpbrk($query, " ,")) {
3259
+            // ("([^"]*?)"|[^" ,]+)((, )+)?
3260
+            // '/([^" ,]+|".*?[^\\\\]")(,|\s)\s*/'
3261
+            if(!preg_match_all('/("([^"]*?)"|[^"\s,]+)((,\s)+)?/', $query, $m)) {
3262
+                return false;
3263
+            }
3264
+            $qterms = $m[1];
3265
+        } else {
3266
+            $qterms = array($query);
3267
+        }
3268
+        $terms = $must_terms = $not_terms = array();
3269
+        foreach($qterms as $item) {
3270
+            if($item[0] == '"') {
3271
+                $item = trim($item, '"');
3272
+            }
3273
+            if($item[0] == '+') {
3274 3274
                 if (strlen($item) > 1) {
3275 3275
                     $must_terms[] = substr($item, 1);
3276 3276
                 }
3277 3277
                 continue;
3278
-			}
3279
-			if($item[0] == '-') {
3278
+            }
3279
+            if($item[0] == '-') {
3280 3280
                 if (strlen($item) > 1) {
3281
-				    $not_terms[] = substr($item, 1);
3281
+                    $not_terms[] = substr($item, 1);
3282 3282
                 }
3283 3283
                 continue;
3284
-			}
3285
-			$terms[] = $item;
3286
-		}
3287
-		return array($terms, $must_terms, $not_terms);
3288
-	}
3284
+            }
3285
+            $terms[] = $item;
3286
+        }
3287
+        return array($terms, $must_terms, $not_terms);
3288
+    }
3289 3289
 
3290 3290
     // Methods to check respective queries
3291
-	protected $standardQueries = array(
3292
-		'ALTER TABLE' => 'verifyAlterTable',
3293
-		'DROP TABLE' => 'verifyDropTable',
3294
-		'CREATE TABLE' => 'verifyCreateTable',
3295
-		'INSERT INTO' => 'verifyInsertInto',
3296
-		'UPDATE' => 'verifyUpdate',
3297
-		'DELETE FROM' => 'verifyDeleteFrom',
3298
-	);
3291
+    protected $standardQueries = array(
3292
+        'ALTER TABLE' => 'verifyAlterTable',
3293
+        'DROP TABLE' => 'verifyDropTable',
3294
+        'CREATE TABLE' => 'verifyCreateTable',
3295
+        'INSERT INTO' => 'verifyInsertInto',
3296
+        'UPDATE' => 'verifyUpdate',
3297
+        'DELETE FROM' => 'verifyDeleteFrom',
3298
+    );
3299 3299
 
3300 3300
 
3301 3301
     /**
@@ -3303,8 +3303,8 @@  discard block
 block discarded – undo
3303 3303
      * @param string $query SQL query
3304 3304
      * @return string
3305 3305
      */
3306
-	protected function extractTableName($query)
3307
-	{
3306
+    protected function extractTableName($query)
3307
+    {
3308 3308
         $query = preg_replace('/[^A-Za-z0-9_\s]/', "", $query);
3309 3309
         $query = trim(str_replace(array_keys($this->standardQueries), '', $query));
3310 3310
 
@@ -3313,7 +3313,7 @@  discard block
 block discarded – undo
3313 3313
         $table = substr($query, 0, $end);
3314 3314
 
3315 3315
         return $table;
3316
-	}
3316
+    }
3317 3317
 
3318 3318
     /**
3319 3319
      * Verify SQl statement using per-DB verification function
@@ -3322,284 +3322,284 @@  discard block
 block discarded – undo
3322 3322
      * @param array $skipTables List of blacklisted tables that aren't checked
3323 3323
      * @return string
3324 3324
      */
3325
-	public function verifySQLStatement($query, $skipTables)
3326
-	{
3327
-		$query = trim($query);
3328
-		foreach($this->standardQueries as $qstart => $check) {
3329
-			if(strncasecmp($qstart, $query, strlen($qstart)) == 0) {
3330
-				if(is_callable(array($this, $check))) {
3331
-					$table = $this->extractTableName($query);
3332
-					if(!in_array($table, $skipTables)) {
3333
-						return call_user_func(array($this, $check), $table, $query);
3334
-					} else {
3335
-						$this->log->debug("Skipping table $table as blacklisted");
3336
-					}
3337
-				} else {
3338
-					$this->log->debug("No verification for $qstart on {$this->dbType}");
3339
-				}
3340
-				break;
3341
-			}
3342
-		}
3343
-		return "";
3344
-	}
3345
-
3346
-	/**
3347
-	 * Tests an CREATE TABLE query
3348
-	 * @param string $table The table name to get DDL
3349
-	 * @param string $query The query to test.
3350
-	 * @return string Non-empty if error found
3351
-	 */
3352
-	protected function verifyCreateTable($table, $query)
3353
-	{
3354
-		$this->log->debug('verifying CREATE statement...');
3355
-
3356
-		// rewrite DDL with _temp name
3357
-		$this->log->debug('testing query: ['.$query.']');
3358
-		$tempname = $table."__uw_temp";
3359
-		$tempTableQuery = str_replace("CREATE TABLE {$table}", "CREATE TABLE $tempname", $query);
3360
-
3361
-		if(strpos($tempTableQuery, '__uw_temp') === false) {
3362
-			return 'Could not use a temp table to test query!';
3363
-		}
3364
-
3365
-		$this->query($tempTableQuery, false, "Preflight Failed for: {$query}");
3366
-
3367
-		$error = $this->lastError(); // empty on no-errors
3368
-		if(!empty($error)) {
3369
-			return $error;
3370
-		}
3371
-
3372
-		// check if table exists
3373
-		$this->log->debug('testing for table: '.$table);
3374
-		if(!$this->tableExists($tempname)) {
3375
-			return "Failed to create temp table!";
3376
-		}
3377
-
3378
-		$this->dropTableName($tempname);
3379
-		return '';
3380
-	}
3381
-
3382
-	/**
3383
-	 * Execute multiple queries one after another
3384
-	 * @param array $sqls Queries
3385
-	 * @param bool $dieOnError Die on error, passed to query()
3386
-	 * @param string $msg Error message, passed to query()
3387
-	 * @param bool $suppress Supress errors, passed to query()
3388
-	 * @return resource|bool result set or success/failure bool
3389
-	 */
3390
-	public function queryArray(array $sqls, $dieOnError = false, $msg = '', $suppress = false)
3391
-	{
3392
-		$last = true;
3393
-		foreach($sqls as $sql) {
3394
-			if(!($last = $this->query($sql, $dieOnError, $msg, $suppress))) {
3395
-				break;
3396
-			}
3397
-		}
3398
-		return $last;
3399
-	}
3400
-
3401
-	/**
3402
-	 * Fetches the next row in the query result into an associative array
3403
-	 *
3404
-	 * @param  resource $result
3405
-	 * @param  bool $encode Need to HTML-encode the result?
3406
-	 * @return array    returns false if there are no more rows available to fetch
3407
-	 */
3408
-	public function fetchByAssoc($result, $encode = true)
3409
-	{
3410
-	    if (empty($result))	return false;
3411
-
3412
-	    if(is_int($encode) && func_num_args() == 3) {
3413
-	        // old API: $result, $rowNum, $encode
3414
-	        $GLOBALS['log']->deprecated("Using row number in fetchByAssoc is not portable and no longer supported. Please fix your code.");
3415
-	        $encode = func_get_arg(2);
3416
-	    }
3417
-	    $row = $this->fetchRow($result);
3418
-	    if (!empty($row) && $encode && $this->encode) {
3419
-	    	return array_map('to_html', $row);
3420
-	    } else {
3421
-	       return $row;
3422
-	    }
3423
-	}
3424
-
3425
-	/**
3426
-	 * Get DB driver name used for install/upgrade scripts
3427
-	 * @return string
3428
-	 */
3429
-	public function getScriptName()
3430
-	{
3431
-		// Usually the same name as dbType
3432
-		return $this->dbType;
3433
-	}
3434
-
3435
-	/**
3436
-	 * Set database options
3437
-	 * Options are usually db-dependant and derive from $config['dbconfigoption']
3438
-	 * @param array $options
3439
-	 * @return DBManager
3440
-	 */
3441
-	public function setOptions($options)
3442
-	{
3443
-	    $this->options = $options;
3444
-	    return $this;
3445
-	}
3446
-
3447
-	/**
3448
-	 * Get DB options
3449
-	 * @return array
3450
-	 */
3451
-	public function getOptions()
3452
-	{
3453
-	    return $this->options;
3454
-	}
3455
-
3456
-	/**
3457
-	 * Get DB option by name
3458
-	 * @param string $option Option name
3459
-	 * @return mixed Option value or null if doesn't exist
3460
-	 */
3461
-	public function getOption($option)
3462
-	{
3463
-	    if(isset($this->options[$option])) {
3464
-	        return $this->options[$option];
3465
-	    }
3466
-	    return null;
3467
-	}
3468
-
3469
-	/**
3470
-	 * Commits pending changes to the database when the driver is setup to support transactions.
3471
-	 * Note that the default implementation is applicable for transaction-less or auto commit scenarios.
3472
-	 * @abstract
3473
-	 * @return bool true if commit succeeded, false if it failed
3474
-	 */
3475
-	public function commit()
3476
-	{
3477
-		$this->log->info("DBManager.commit() stub");
3478
-		return true;
3479
-	}
3480
-
3481
-	/**
3482
-	 * Rollsback pending changes to the database when the driver is setup to support transactions.
3483
-	 * Note that the default implementation is applicable for transaction-less or auto commit scenarios.
3484
-	 * Since rollbacks cannot be done, this implementation always returns false.
3485
-	 * @abstract
3486
-	 * @return bool true if rollback succeeded, false if it failed
3487
-	 */
3488
-	public function rollback()
3489
-	{
3490
-		$this->log->info("DBManager.rollback() stub");
3491
-		return false;
3492
-	}
3493
-
3494
-	/**
3495
-	 * Check if this DB name is valid
3496
-	 *
3497
-	 * @param string $name
3498
-	 * @return bool
3499
-	 */
3500
-	public function isDatabaseNameValid($name)
3501
-	{
3502
-		// Generic case - no slashes, no dots
3503
-		return preg_match('#[/.\\\\]#', $name)==0;
3504
-	}
3505
-
3506
-	/**
3507
-	 * Check special requirements for DB installation.
3508
-	 * @abstract
3509
-	 * If everything is OK, return true.
3510
-	 * If something's wrong, return array of error code and parameters
3511
-	 * @return mixed
3512
-	 */
3513
-	public function canInstall()
3514
-	{
3515
-		return true;
3516
-	}
3517
-
3518
-	/**
3519
-	 * @abstract
3325
+    public function verifySQLStatement($query, $skipTables)
3326
+    {
3327
+        $query = trim($query);
3328
+        foreach($this->standardQueries as $qstart => $check) {
3329
+            if(strncasecmp($qstart, $query, strlen($qstart)) == 0) {
3330
+                if(is_callable(array($this, $check))) {
3331
+                    $table = $this->extractTableName($query);
3332
+                    if(!in_array($table, $skipTables)) {
3333
+                        return call_user_func(array($this, $check), $table, $query);
3334
+                    } else {
3335
+                        $this->log->debug("Skipping table $table as blacklisted");
3336
+                    }
3337
+                } else {
3338
+                    $this->log->debug("No verification for $qstart on {$this->dbType}");
3339
+                }
3340
+                break;
3341
+            }
3342
+        }
3343
+        return "";
3344
+    }
3345
+
3346
+    /**
3347
+     * Tests an CREATE TABLE query
3348
+     * @param string $table The table name to get DDL
3349
+     * @param string $query The query to test.
3350
+     * @return string Non-empty if error found
3351
+     */
3352
+    protected function verifyCreateTable($table, $query)
3353
+    {
3354
+        $this->log->debug('verifying CREATE statement...');
3355
+
3356
+        // rewrite DDL with _temp name
3357
+        $this->log->debug('testing query: ['.$query.']');
3358
+        $tempname = $table."__uw_temp";
3359
+        $tempTableQuery = str_replace("CREATE TABLE {$table}", "CREATE TABLE $tempname", $query);
3360
+
3361
+        if(strpos($tempTableQuery, '__uw_temp') === false) {
3362
+            return 'Could not use a temp table to test query!';
3363
+        }
3364
+
3365
+        $this->query($tempTableQuery, false, "Preflight Failed for: {$query}");
3366
+
3367
+        $error = $this->lastError(); // empty on no-errors
3368
+        if(!empty($error)) {
3369
+            return $error;
3370
+        }
3371
+
3372
+        // check if table exists
3373
+        $this->log->debug('testing for table: '.$table);
3374
+        if(!$this->tableExists($tempname)) {
3375
+            return "Failed to create temp table!";
3376
+        }
3377
+
3378
+        $this->dropTableName($tempname);
3379
+        return '';
3380
+    }
3381
+
3382
+    /**
3383
+     * Execute multiple queries one after another
3384
+     * @param array $sqls Queries
3385
+     * @param bool $dieOnError Die on error, passed to query()
3386
+     * @param string $msg Error message, passed to query()
3387
+     * @param bool $suppress Supress errors, passed to query()
3388
+     * @return resource|bool result set or success/failure bool
3389
+     */
3390
+    public function queryArray(array $sqls, $dieOnError = false, $msg = '', $suppress = false)
3391
+    {
3392
+        $last = true;
3393
+        foreach($sqls as $sql) {
3394
+            if(!($last = $this->query($sql, $dieOnError, $msg, $suppress))) {
3395
+                break;
3396
+            }
3397
+        }
3398
+        return $last;
3399
+    }
3400
+
3401
+    /**
3402
+     * Fetches the next row in the query result into an associative array
3403
+     *
3404
+     * @param  resource $result
3405
+     * @param  bool $encode Need to HTML-encode the result?
3406
+     * @return array    returns false if there are no more rows available to fetch
3407
+     */
3408
+    public function fetchByAssoc($result, $encode = true)
3409
+    {
3410
+        if (empty($result))	return false;
3411
+
3412
+        if(is_int($encode) && func_num_args() == 3) {
3413
+            // old API: $result, $rowNum, $encode
3414
+            $GLOBALS['log']->deprecated("Using row number in fetchByAssoc is not portable and no longer supported. Please fix your code.");
3415
+            $encode = func_get_arg(2);
3416
+        }
3417
+        $row = $this->fetchRow($result);
3418
+        if (!empty($row) && $encode && $this->encode) {
3419
+            return array_map('to_html', $row);
3420
+        } else {
3421
+            return $row;
3422
+        }
3423
+    }
3424
+
3425
+    /**
3426
+     * Get DB driver name used for install/upgrade scripts
3427
+     * @return string
3428
+     */
3429
+    public function getScriptName()
3430
+    {
3431
+        // Usually the same name as dbType
3432
+        return $this->dbType;
3433
+    }
3434
+
3435
+    /**
3436
+     * Set database options
3437
+     * Options are usually db-dependant and derive from $config['dbconfigoption']
3438
+     * @param array $options
3439
+     * @return DBManager
3440
+     */
3441
+    public function setOptions($options)
3442
+    {
3443
+        $this->options = $options;
3444
+        return $this;
3445
+    }
3446
+
3447
+    /**
3448
+     * Get DB options
3449
+     * @return array
3450
+     */
3451
+    public function getOptions()
3452
+    {
3453
+        return $this->options;
3454
+    }
3455
+
3456
+    /**
3457
+     * Get DB option by name
3458
+     * @param string $option Option name
3459
+     * @return mixed Option value or null if doesn't exist
3460
+     */
3461
+    public function getOption($option)
3462
+    {
3463
+        if(isset($this->options[$option])) {
3464
+            return $this->options[$option];
3465
+        }
3466
+        return null;
3467
+    }
3468
+
3469
+    /**
3470
+     * Commits pending changes to the database when the driver is setup to support transactions.
3471
+     * Note that the default implementation is applicable for transaction-less or auto commit scenarios.
3472
+     * @abstract
3473
+     * @return bool true if commit succeeded, false if it failed
3474
+     */
3475
+    public function commit()
3476
+    {
3477
+        $this->log->info("DBManager.commit() stub");
3478
+        return true;
3479
+    }
3480
+
3481
+    /**
3482
+     * Rollsback pending changes to the database when the driver is setup to support transactions.
3483
+     * Note that the default implementation is applicable for transaction-less or auto commit scenarios.
3484
+     * Since rollbacks cannot be done, this implementation always returns false.
3485
+     * @abstract
3486
+     * @return bool true if rollback succeeded, false if it failed
3487
+     */
3488
+    public function rollback()
3489
+    {
3490
+        $this->log->info("DBManager.rollback() stub");
3491
+        return false;
3492
+    }
3493
+
3494
+    /**
3495
+     * Check if this DB name is valid
3496
+     *
3497
+     * @param string $name
3498
+     * @return bool
3499
+     */
3500
+    public function isDatabaseNameValid($name)
3501
+    {
3502
+        // Generic case - no slashes, no dots
3503
+        return preg_match('#[/.\\\\]#', $name)==0;
3504
+    }
3505
+
3506
+    /**
3507
+     * Check special requirements for DB installation.
3508
+     * @abstract
3509
+     * If everything is OK, return true.
3510
+     * If something's wrong, return array of error code and parameters
3511
+     * @return mixed
3512
+     */
3513
+    public function canInstall()
3514
+    {
3515
+        return true;
3516
+    }
3517
+
3518
+    /**
3519
+     * @abstract
3520 3520
      * Code run on new database before installing
3521
-	 */
3522
-	public function preInstall()
3523
-	{
3524
-	}
3521
+     */
3522
+    public function preInstall()
3523
+    {
3524
+    }
3525
+
3526
+    /**
3527
+     * @abstract
3528
+     * Code run on new database after installing
3529
+     */
3530
+    public function postInstall()
3531
+    {
3532
+    }
3533
+
3534
+    /**
3535
+     * Disable keys on the table
3536
+     * @abstract
3537
+     * @param string $tableName
3538
+     */
3539
+    public function disableKeys($tableName)
3540
+    {
3541
+    }
3525 3542
 
3526
-	/**
3543
+    /**
3544
+     * Re-enable keys on the table
3527 3545
      * @abstract
3528
-	 * Code run on new database after installing
3529
-	 */
3530
-	public function postInstall()
3531
-	{
3532
-	}
3533
-
3534
-	/**
3535
-	 * Disable keys on the table
3536
-	 * @abstract
3537
-	 * @param string $tableName
3538
-	 */
3539
-	public function disableKeys($tableName)
3540
-	{
3541
-	}
3542
-
3543
-	/**
3544
-	 * Re-enable keys on the table
3545
-	 * @abstract
3546
-	 * @param string $tableName
3547
-	 */
3548
-	public function enableKeys($tableName)
3549
-	{
3550
-	}
3551
-
3552
-	/**
3553
-	 * Quote string in DB-specific manner
3554
-	 * @param string $string
3555
-	 * @return string
3556
-	 */
3557
-	abstract public function quote($string);
3546
+     * @param string $tableName
3547
+     */
3548
+    public function enableKeys($tableName)
3549
+    {
3550
+    }
3551
+
3552
+    /**
3553
+     * Quote string in DB-specific manner
3554
+     * @param string $string
3555
+     * @return string
3556
+     */
3557
+    abstract public function quote($string);
3558 3558
 
3559 3559
     abstract public function quoteIdentifier($string);
3560 3560
 
3561
-	/**
3562
-	 * Use when you need to convert a database string to a different value; this function does it in a
3563
-	 * database-backend aware way
3564
-	 * Supported conversions:
3565
-	 *      today		return current date
3566
-	 *      left		Take substring from the left
3567
-	 *      date_format	Format date as string, supports %Y-%m-%d, %Y-%m, %Y
3561
+    /**
3562
+     * Use when you need to convert a database string to a different value; this function does it in a
3563
+     * database-backend aware way
3564
+     * Supported conversions:
3565
+     *      today		return current date
3566
+     *      left		Take substring from the left
3567
+     *      date_format	Format date as string, supports %Y-%m-%d, %Y-%m, %Y
3568 3568
      *      time_format Format time as string
3569 3569
      *      date        Convert date string to datetime value
3570 3570
      *      time        Convert time string to datetime value
3571
-	 *      datetime	Convert datetime string to datetime value
3572
-	 *      ifnull		If var is null, use default value
3573
-	 *      concat		Concatenate strings
3574
-	 *      quarter		Quarter number of the date
3575
-	 *      length		Length of string
3576
-	 *      month		Month number of the date
3577
-	 *      add_date	Add specified interval to a date
3571
+     *      datetime	Convert datetime string to datetime value
3572
+     *      ifnull		If var is null, use default value
3573
+     *      concat		Concatenate strings
3574
+     *      quarter		Quarter number of the date
3575
+     *      length		Length of string
3576
+     *      month		Month number of the date
3577
+     *      add_date	Add specified interval to a date
3578 3578
      *      add_time    Add time interval to a date
3579 3579
      *      text2char   Convert text field to varchar
3580
-	 *
3581
-	 * @param string $string database string to convert
3582
-	 * @param string $type type of conversion to do
3583
-	 * @param array  $additional_parameters optional, additional parameters to pass to the db function
3584
-	 * @return string
3585
-	 */
3586
-	abstract public function convert($string, $type, array $additional_parameters = array());
3587
-
3588
-	/**
3589
-	 * Converts from Database data to app data
3590
-	 *
3591
-	 * Supported types
3592
-	 * - date
3593
-	 * - time
3594
-	 * - datetime
3580
+     *
3581
+     * @param string $string database string to convert
3582
+     * @param string $type type of conversion to do
3583
+     * @param array  $additional_parameters optional, additional parameters to pass to the db function
3584
+     * @return string
3585
+     */
3586
+    abstract public function convert($string, $type, array $additional_parameters = array());
3587
+
3588
+    /**
3589
+     * Converts from Database data to app data
3590
+     *
3591
+     * Supported types
3592
+     * - date
3593
+     * - time
3594
+     * - datetime
3595 3595
      * - datetimecombo
3596 3596
      * - timestamp
3597
-	 *
3598
-	 * @param string $string database string to convert
3599
-	 * @param string $type type of conversion to do
3600
-	 * @return string
3601
-	 */
3602
-	abstract public function fromConvert($string, $type);
3597
+     *
3598
+     * @param string $string database string to convert
3599
+     * @param string $type type of conversion to do
3600
+     * @return string
3601
+     */
3602
+    abstract public function fromConvert($string, $type);
3603 3603
 
3604 3604
     /**
3605 3605
      * Parses and runs queries
@@ -3611,7 +3611,7 @@  discard block
 block discarded – undo
3611 3611
      * @param  bool     $keepResult Keep query result in the object?
3612 3612
      * @return resource|bool result set or success/failure bool
3613 3613
      */
3614
-	abstract public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false);
3614
+    abstract public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false);
3615 3615
 
3616 3616
     /**
3617 3617
      * Runs a limit query: one where we specify where to start getting records and how many to get
@@ -3624,173 +3624,173 @@  discard block
 block discarded – undo
3624 3624
      * @param  bool     $execute Execute or return SQL?
3625 3625
      * @return resource query result
3626 3626
      */
3627
-	abstract function limitQuery($sql, $start, $count, $dieOnError = false, $msg = '', $execute = true);
3628
-
3629
-
3630
-	/**
3631
-	 * Free Database result
3632
-	 * @param resource $dbResult
3633
-	 */
3634
-	abstract protected function freeDbResult($dbResult);
3635
-
3636
-	/**
3637
-	 * Rename column in the DB
3638
-	 * @param string $tablename
3639
-	 * @param string $column
3640
-	 * @param string $newname
3641
-	 */
3642
-	abstract function renameColumnSQL($tablename, $column, $newname);
3643
-
3644
-	/**
3645
-	 * Returns definitions of all indies for passed table.
3646
-	 *
3647
-	 * return will is a multi-dimensional array that
3648
-	 * categorizes the index definition by types, unique, primary and index.
3649
-	 * <code>
3650
-	 * <?php
3651
-	 * array(                                                              O
3652
-	 *       'index1'=> array (
3653
-	 *           'name'   => 'index1',
3654
-	 *           'type'   => 'primary',
3655
-	 *           'fields' => array('field1','field2')
3656
-	 *           )
3657
-	 *       )
3658
-	 * ?>
3659
-	 * </code>
3660
-	 * This format is similar to how indicies are defined in vardef file.
3661
-	 *
3662
-	 * @param  string $tablename
3663
-	 * @return array
3664
-	 */
3665
-	abstract public function get_indices($tablename);
3666
-
3667
-	/**
3668
-	 * Returns definitions of all indies for passed table.
3669
-	 *
3670
-	 * return will is a multi-dimensional array that
3671
-	 * categorizes the index definition by types, unique, primary and index.
3672
-	 * <code>
3673
-	 * <?php
3674
-	 * array(
3675
-	 *       'field1'=> array (
3676
-	 *           'name'   => 'field1',
3677
-	 *           'type'   => 'varchar',
3678
-	 *           'len' => '200'
3679
-	 *           )
3680
-	 *       )
3681
-	 * ?>
3682
-	 * </code>
3683
-	 * This format is similar to how indicies are defined in vardef file.
3684
-	 *
3685
-	 * @param  string $tablename
3686
-	 * @return array
3687
-	 */
3688
-	abstract public function get_columns($tablename);
3689
-
3690
-	/**
3691
-	 * Generates alter constraint statement given a table name and vardef definition.
3692
-	 *
3693
-	 * Supports both adding and droping a constraint.
3694
-	 *
3695
-	 * @param  string $table      tablename
3696
-	 * @param  array  $definition field definition
3697
-	 * @param  bool   $drop       true if we are dropping the constraint, false if we are adding it
3698
-	 * @return string SQL statement
3699
-	 */
3700
-	abstract public function add_drop_constraint($table, $definition, $drop = false);
3701
-
3702
-	/**
3703
-	 * Returns the description of fields based on the result
3704
-	 *
3705
-	 * @param  resource $result
3706
-	 * @param  boolean  $make_lower_case
3707
-	 * @return array field array
3708
-	 */
3709
-	abstract public function getFieldsArray($result, $make_lower_case = false);
3710
-
3711
-	/**
3712
-	 * Returns an array of tables for this database
3713
-	 *
3714
-	 * @return	array|false 	an array of with table names, false if no tables found
3715
-	 */
3716
-	abstract public function getTablesArray();
3717
-
3718
-	/**
3719
-	 * Return's the version of the database
3720
-	 *
3721
-	 * @return string
3722
-	 */
3723
-	abstract public function version();
3724
-
3725
-	/**
3726
-	 * Checks if a table with the name $tableName exists
3727
-	 * and returns true if it does or false otherwise
3728
-	 *
3729
-	 * @param  string $tableName
3730
-	 * @return bool
3731
-	 */
3732
-	abstract public function tableExists($tableName);
3733
-
3734
-	/**
3735
-	 * Fetches the next row in the query result into an associative array
3736
-	 *
3737
-	 * @param  resource $result
3738
-	 * @return array    returns false if there are no more rows available to fetch
3739
-	 */
3740
-	abstract public function fetchRow($result);
3741
-
3742
-	/**
3743
-	 * Connects to the database backend
3744
-	 *
3745
-	 * Takes in the database settings and opens a database connection based on those
3746
-	 * will open either a persistent or non-persistent connection.
3747
-	 * If a persistent connection is desired but not available it will defualt to non-persistent
3748
-	 *
3749
-	 * configOptions must include
3750
-	 * db_host_name - server ip
3751
-	 * db_user_name - database user name
3752
-	 * db_password - database password
3753
-	 *
3754
-	 * @param array   $configOptions
3755
-	 * @param boolean $dieOnError
3756
-	 */
3757
-	abstract public function connect(array $configOptions = null, $dieOnError = false);
3758
-
3759
-	/**
3760
-	 * Generates sql for create table statement for a bean.
3761
-	 *
3762
-	 * @param  string $tablename
3763
-	 * @param  array  $fieldDefs
3764
-	 * @param  array  $indices
3765
-	 * @return string SQL Create Table statement
3766
-	 */
3767
-	abstract public function createTableSQLParams($tablename, $fieldDefs, $indices);
3768
-
3769
-	/**
3770
-	 * Generates the SQL for changing columns
3771
-	 *
3772
-	 * @param string $tablename
3773
-	 * @param array  $fieldDefs
3774
-	 * @param string $action
3775
-	 * @param bool   $ignoreRequired Optional, true if we should ignor this being a required field
3776
-	 * @return string|array
3777
-	 */
3778
-	abstract protected function changeColumnSQL($tablename, $fieldDefs, $action, $ignoreRequired = false);
3779
-
3780
-	/**
3781
-	 * Disconnects from the database
3782
-	 *
3783
-	 * Also handles any cleanup needed
3784
-	 */
3785
-	abstract public function disconnect();
3786
-
3787
-	/**
3788
-	 * Get last database error
3789
-	 * This function should return last error as reported by DB driver
3790
-	 * and should return false if no error condition happened
3791
-	 * @return string|false Error message or false if no error happened
3792
-	 */
3793
-	abstract public function lastDbError();
3627
+    abstract function limitQuery($sql, $start, $count, $dieOnError = false, $msg = '', $execute = true);
3628
+
3629
+
3630
+    /**
3631
+     * Free Database result
3632
+     * @param resource $dbResult
3633
+     */
3634
+    abstract protected function freeDbResult($dbResult);
3635
+
3636
+    /**
3637
+     * Rename column in the DB
3638
+     * @param string $tablename
3639
+     * @param string $column
3640
+     * @param string $newname
3641
+     */
3642
+    abstract function renameColumnSQL($tablename, $column, $newname);
3643
+
3644
+    /**
3645
+     * Returns definitions of all indies for passed table.
3646
+     *
3647
+     * return will is a multi-dimensional array that
3648
+     * categorizes the index definition by types, unique, primary and index.
3649
+     * <code>
3650
+     * <?php
3651
+     * array(                                                              O
3652
+     *       'index1'=> array (
3653
+     *           'name'   => 'index1',
3654
+     *           'type'   => 'primary',
3655
+     *           'fields' => array('field1','field2')
3656
+     *           )
3657
+     *       )
3658
+     * ?>
3659
+     * </code>
3660
+     * This format is similar to how indicies are defined in vardef file.
3661
+     *
3662
+     * @param  string $tablename
3663
+     * @return array
3664
+     */
3665
+    abstract public function get_indices($tablename);
3666
+
3667
+    /**
3668
+     * Returns definitions of all indies for passed table.
3669
+     *
3670
+     * return will is a multi-dimensional array that
3671
+     * categorizes the index definition by types, unique, primary and index.
3672
+     * <code>
3673
+     * <?php
3674
+     * array(
3675
+     *       'field1'=> array (
3676
+     *           'name'   => 'field1',
3677
+     *           'type'   => 'varchar',
3678
+     *           'len' => '200'
3679
+     *           )
3680
+     *       )
3681
+     * ?>
3682
+     * </code>
3683
+     * This format is similar to how indicies are defined in vardef file.
3684
+     *
3685
+     * @param  string $tablename
3686
+     * @return array
3687
+     */
3688
+    abstract public function get_columns($tablename);
3689
+
3690
+    /**
3691
+     * Generates alter constraint statement given a table name and vardef definition.
3692
+     *
3693
+     * Supports both adding and droping a constraint.
3694
+     *
3695
+     * @param  string $table      tablename
3696
+     * @param  array  $definition field definition
3697
+     * @param  bool   $drop       true if we are dropping the constraint, false if we are adding it
3698
+     * @return string SQL statement
3699
+     */
3700
+    abstract public function add_drop_constraint($table, $definition, $drop = false);
3701
+
3702
+    /**
3703
+     * Returns the description of fields based on the result
3704
+     *
3705
+     * @param  resource $result
3706
+     * @param  boolean  $make_lower_case
3707
+     * @return array field array
3708
+     */
3709
+    abstract public function getFieldsArray($result, $make_lower_case = false);
3710
+
3711
+    /**
3712
+     * Returns an array of tables for this database
3713
+     *
3714
+     * @return	array|false 	an array of with table names, false if no tables found
3715
+     */
3716
+    abstract public function getTablesArray();
3717
+
3718
+    /**
3719
+     * Return's the version of the database
3720
+     *
3721
+     * @return string
3722
+     */
3723
+    abstract public function version();
3724
+
3725
+    /**
3726
+     * Checks if a table with the name $tableName exists
3727
+     * and returns true if it does or false otherwise
3728
+     *
3729
+     * @param  string $tableName
3730
+     * @return bool
3731
+     */
3732
+    abstract public function tableExists($tableName);
3733
+
3734
+    /**
3735
+     * Fetches the next row in the query result into an associative array
3736
+     *
3737
+     * @param  resource $result
3738
+     * @return array    returns false if there are no more rows available to fetch
3739
+     */
3740
+    abstract public function fetchRow($result);
3741
+
3742
+    /**
3743
+     * Connects to the database backend
3744
+     *
3745
+     * Takes in the database settings and opens a database connection based on those
3746
+     * will open either a persistent or non-persistent connection.
3747
+     * If a persistent connection is desired but not available it will defualt to non-persistent
3748
+     *
3749
+     * configOptions must include
3750
+     * db_host_name - server ip
3751
+     * db_user_name - database user name
3752
+     * db_password - database password
3753
+     *
3754
+     * @param array   $configOptions
3755
+     * @param boolean $dieOnError
3756
+     */
3757
+    abstract public function connect(array $configOptions = null, $dieOnError = false);
3758
+
3759
+    /**
3760
+     * Generates sql for create table statement for a bean.
3761
+     *
3762
+     * @param  string $tablename
3763
+     * @param  array  $fieldDefs
3764
+     * @param  array  $indices
3765
+     * @return string SQL Create Table statement
3766
+     */
3767
+    abstract public function createTableSQLParams($tablename, $fieldDefs, $indices);
3768
+
3769
+    /**
3770
+     * Generates the SQL for changing columns
3771
+     *
3772
+     * @param string $tablename
3773
+     * @param array  $fieldDefs
3774
+     * @param string $action
3775
+     * @param bool   $ignoreRequired Optional, true if we should ignor this being a required field
3776
+     * @return string|array
3777
+     */
3778
+    abstract protected function changeColumnSQL($tablename, $fieldDefs, $action, $ignoreRequired = false);
3779
+
3780
+    /**
3781
+     * Disconnects from the database
3782
+     *
3783
+     * Also handles any cleanup needed
3784
+     */
3785
+    abstract public function disconnect();
3786
+
3787
+    /**
3788
+     * Get last database error
3789
+     * This function should return last error as reported by DB driver
3790
+     * and should return false if no error condition happened
3791
+     * @return string|false Error message or false if no error happened
3792
+     */
3793
+    abstract public function lastDbError();
3794 3794
 
3795 3795
     /**
3796 3796
      * Check if this query is valid
@@ -3798,82 +3798,82 @@  discard block
 block discarded – undo
3798 3798
      * @param string $query
3799 3799
      * @return bool
3800 3800
      */
3801
-	abstract public function validateQuery($query);
3802
-
3803
-	/**
3804
-	 * Check if this driver can be used
3805
-	 * @return bool
3806
-	 */
3807
-	abstract public function valid();
3808
-
3809
-	/**
3810
-	 * Check if certain database exists
3811
-	 * @param string $dbname
3812
-	 */
3813
-	abstract public function dbExists($dbname);
3814
-
3815
-	/**
3816
-	 * Get tables like expression
3817
-	 * @param string $like Expression describing tables
3818
-	 * @return array
3819
-	 */
3820
-	abstract public function tablesLike($like);
3821
-
3822
-	/**
3823
-	 * Create a database
3824
-	 * @param string $dbname
3825
-	 */
3826
-	abstract public function createDatabase($dbname);
3827
-
3828
-	/**
3829
-	 * Drop a database
3830
-	 * @param string $dbname
3831
-	 */
3832
-	abstract public function dropDatabase($dbname);
3833
-
3834
-	/**
3835
-	 * Get database configuration information (DB-dependent)
3836
-	 * @return array|null
3837
-	 */
3838
-	abstract public function getDbInfo();
3839
-
3840
-	/**
3841
-	 * Check if certain DB user exists
3842
-	 * @param string $username
3843
-	 */
3844
-	abstract public function userExists($username);
3845
-
3846
-	/**
3847
-	 * Create DB user
3848
-	 * @param string $database_name
3849
-	 * @param string $host_name
3850
-	 * @param string $user
3851
-	 * @param string $password
3852
-	 */
3853
-	abstract public function createDbUser($database_name, $host_name, $user, $password);
3854
-
3855
-	/**
3856
-	 * Check if the database supports fulltext indexing
3857
-	 * Note that database driver can be capable of supporting FT (see supports('fulltext))
3858
-	 * but particular instance can still have it disabled
3859
-	 * @return bool
3860
-	 */
3861
-	abstract public function full_text_indexing_installed();
3862
-
3863
-	/**
3864
-	 * Generate fulltext query from set of terms
3865
-	 * @param string $field Field to search against
3866
-	 * @param array $terms Search terms that may be or not be in the result
3867
-	 * @param array $must_terms Search terms that have to be in the result
3868
-	 * @param array $exclude_terms Search terms that have to be not in the result
3869
-	 */
3870
-	abstract public function getFulltextQuery($field, $terms, $must_terms = array(), $exclude_terms = array());
3871
-
3872
-	/**
3873
-	 * Get install configuration for this DB
3874
-	 * @return array
3875
-	 */
3876
-	abstract public function installConfig();
3801
+    abstract public function validateQuery($query);
3802
+
3803
+    /**
3804
+     * Check if this driver can be used
3805
+     * @return bool
3806
+     */
3807
+    abstract public function valid();
3808
+
3809
+    /**
3810
+     * Check if certain database exists
3811
+     * @param string $dbname
3812
+     */
3813
+    abstract public function dbExists($dbname);
3814
+
3815
+    /**
3816
+     * Get tables like expression
3817
+     * @param string $like Expression describing tables
3818
+     * @return array
3819
+     */
3820
+    abstract public function tablesLike($like);
3821
+
3822
+    /**
3823
+     * Create a database
3824
+     * @param string $dbname
3825
+     */
3826
+    abstract public function createDatabase($dbname);
3827
+
3828
+    /**
3829
+     * Drop a database
3830
+     * @param string $dbname
3831
+     */
3832
+    abstract public function dropDatabase($dbname);
3833
+
3834
+    /**
3835
+     * Get database configuration information (DB-dependent)
3836
+     * @return array|null
3837
+     */
3838
+    abstract public function getDbInfo();
3839
+
3840
+    /**
3841
+     * Check if certain DB user exists
3842
+     * @param string $username
3843
+     */
3844
+    abstract public function userExists($username);
3845
+
3846
+    /**
3847
+     * Create DB user
3848
+     * @param string $database_name
3849
+     * @param string $host_name
3850
+     * @param string $user
3851
+     * @param string $password
3852
+     */
3853
+    abstract public function createDbUser($database_name, $host_name, $user, $password);
3854
+
3855
+    /**
3856
+     * Check if the database supports fulltext indexing
3857
+     * Note that database driver can be capable of supporting FT (see supports('fulltext))
3858
+     * but particular instance can still have it disabled
3859
+     * @return bool
3860
+     */
3861
+    abstract public function full_text_indexing_installed();
3862
+
3863
+    /**
3864
+     * Generate fulltext query from set of terms
3865
+     * @param string $field Field to search against
3866
+     * @param array $terms Search terms that may be or not be in the result
3867
+     * @param array $must_terms Search terms that have to be in the result
3868
+     * @param array $exclude_terms Search terms that have to be not in the result
3869
+     */
3870
+    abstract public function getFulltextQuery($field, $terms, $must_terms = array(), $exclude_terms = array());
3871
+
3872
+    /**
3873
+     * Get install configuration for this DB
3874
+     * @return array
3875
+     */
3876
+    abstract public function installConfig();
3877 3877
 
3878 3878
     /**
3879 3879
      * Returns a DB specific FROM clause which can be used to select against functions.
@@ -3890,5 +3890,5 @@  discard block
 block discarded – undo
3890 3890
      * @abstract
3891 3891
      * @return string
3892 3892
      */
3893
-	abstract public function getGuidSQL();
3893
+    abstract public function getGuidSQL();
3894 3894
 }
Please login to merge, or discard this patch.
include/database/MysqlManager.php 1 patch
Indentation   +1344 added lines, -1344 removed lines patch added patch discarded remove patch
@@ -96,368 +96,368 @@  discard block
 block discarded – undo
96 96
  */
97 97
 class MysqlManager extends DBManager
98 98
 {
99
-	/**
100
-	 * @see DBManager::$dbType
101
-	 */
102
-	public $dbType = 'mysql';
103
-	public $variant = 'mysql';
104
-	public $dbName = 'MySQL';
105
-	public $label = 'LBL_MYSQL';
106
-
107
-	protected $maxNameLengths = array(
108
-		'table' => 64,
109
-		'column' => 64,
110
-		'index' => 64,
111
-		'alias' => 256
112
-	);
113
-
114
-	protected $type_map = array(
115
-			'int'      => 'int',
116
-			'double'   => 'double',
117
-			'float'    => 'float',
118
-			'uint'     => 'int unsigned',
119
-			'ulong'    => 'bigint unsigned',
120
-			'long'     => 'bigint',
121
-			'short'    => 'smallint',
122
-			'varchar'  => 'varchar',
123
-			'text'     => 'text',
124
-			'longtext' => 'longtext',
125
-			'date'     => 'date',
126
-			'enum'     => 'varchar',
127
-			'relate'   => 'varchar',
128
-			'multienum'=> 'text',
129
-			'html'     => 'text',
130
-			'longhtml' => 'longtext',
131
-			'datetime' => 'datetime',
132
-			'datetimecombo' => 'datetime',
133
-			'time'     => 'time',
134
-			'bool'     => 'bool',
135
-			'tinyint'  => 'tinyint',
136
-			'char'     => 'char',
137
-			'blob'     => 'blob',
138
-			'longblob' => 'longblob',
139
-			'currency' => 'decimal(26,6)',
140
-			'decimal'  => 'decimal',
141
-			'decimal2' => 'decimal',
142
-			'id'       => 'char(36)',
143
-			'url'      => 'varchar',
144
-			'encrypt'  => 'varchar',
145
-			'file'     => 'varchar',
146
-			'decimal_tpl' => 'decimal(%d, %d)',
147
-
148
-	);
149
-
150
-	protected $capabilities = array(
151
-		"affected_rows" => true,
152
-		"select_rows" => true,
153
-		"inline_keys" => true,
154
-		"create_user" => true,
155
-		"fulltext" => true,
156
-	    "collation" => true,
157
-	    "create_db" => true,
158
-	    "disable_keys" => true,
159
-	);
160
-
161
-	/**
162
-	 * Parses and runs queries
163
-	 *
164
-	 * @param  string   $sql        SQL Statement to execute
165
-	 * @param  bool     $dieOnError True if we want to call die if the query returns errors
166
-	 * @param  string   $msg        Message to log if error occurs
167
-	 * @param  bool     $suppress   Flag to suppress all error output unless in debug logging mode.
168
-	 * @param  bool     $keepResult True if we want to push this result into the $lastResult array.
169
-	 * @return resource result set
170
-	 */
171
-	public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
172
-	{
173
-		if(is_array($sql)) {
174
-			return $this->queryArray($sql, $dieOnError, $msg, $suppress);
175
-		}
176
-
177
-		parent::countQuery($sql);
178
-		$GLOBALS['log']->info('Query:' . $sql);
179
-		$this->checkConnection();
180
-		$this->query_time = microtime(true);
181
-		$this->lastsql = $sql;
182
-		$result = $suppress?@mysql_query($sql, $this->database):mysql_query($sql, $this->database);
183
-
184
-		$this->query_time = microtime(true) - $this->query_time;
185
-		$GLOBALS['log']->info('Query Execution Time:'.$this->query_time);
186
-
187
-
188
-		if($keepResult)
189
-			$this->lastResult = $result;
190
-
191
-		$this->checkError($msg.' Query Failed:' . $sql . '::', $dieOnError);
192
-		return $result;
193
-	}
99
+    /**
100
+     * @see DBManager::$dbType
101
+     */
102
+    public $dbType = 'mysql';
103
+    public $variant = 'mysql';
104
+    public $dbName = 'MySQL';
105
+    public $label = 'LBL_MYSQL';
106
+
107
+    protected $maxNameLengths = array(
108
+        'table' => 64,
109
+        'column' => 64,
110
+        'index' => 64,
111
+        'alias' => 256
112
+    );
113
+
114
+    protected $type_map = array(
115
+            'int'      => 'int',
116
+            'double'   => 'double',
117
+            'float'    => 'float',
118
+            'uint'     => 'int unsigned',
119
+            'ulong'    => 'bigint unsigned',
120
+            'long'     => 'bigint',
121
+            'short'    => 'smallint',
122
+            'varchar'  => 'varchar',
123
+            'text'     => 'text',
124
+            'longtext' => 'longtext',
125
+            'date'     => 'date',
126
+            'enum'     => 'varchar',
127
+            'relate'   => 'varchar',
128
+            'multienum'=> 'text',
129
+            'html'     => 'text',
130
+            'longhtml' => 'longtext',
131
+            'datetime' => 'datetime',
132
+            'datetimecombo' => 'datetime',
133
+            'time'     => 'time',
134
+            'bool'     => 'bool',
135
+            'tinyint'  => 'tinyint',
136
+            'char'     => 'char',
137
+            'blob'     => 'blob',
138
+            'longblob' => 'longblob',
139
+            'currency' => 'decimal(26,6)',
140
+            'decimal'  => 'decimal',
141
+            'decimal2' => 'decimal',
142
+            'id'       => 'char(36)',
143
+            'url'      => 'varchar',
144
+            'encrypt'  => 'varchar',
145
+            'file'     => 'varchar',
146
+            'decimal_tpl' => 'decimal(%d, %d)',
147
+
148
+    );
149
+
150
+    protected $capabilities = array(
151
+        "affected_rows" => true,
152
+        "select_rows" => true,
153
+        "inline_keys" => true,
154
+        "create_user" => true,
155
+        "fulltext" => true,
156
+        "collation" => true,
157
+        "create_db" => true,
158
+        "disable_keys" => true,
159
+    );
160
+
161
+    /**
162
+     * Parses and runs queries
163
+     *
164
+     * @param  string   $sql        SQL Statement to execute
165
+     * @param  bool     $dieOnError True if we want to call die if the query returns errors
166
+     * @param  string   $msg        Message to log if error occurs
167
+     * @param  bool     $suppress   Flag to suppress all error output unless in debug logging mode.
168
+     * @param  bool     $keepResult True if we want to push this result into the $lastResult array.
169
+     * @return resource result set
170
+     */
171
+    public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
172
+    {
173
+        if(is_array($sql)) {
174
+            return $this->queryArray($sql, $dieOnError, $msg, $suppress);
175
+        }
176
+
177
+        parent::countQuery($sql);
178
+        $GLOBALS['log']->info('Query:' . $sql);
179
+        $this->checkConnection();
180
+        $this->query_time = microtime(true);
181
+        $this->lastsql = $sql;
182
+        $result = $suppress?@mysql_query($sql, $this->database):mysql_query($sql, $this->database);
183
+
184
+        $this->query_time = microtime(true) - $this->query_time;
185
+        $GLOBALS['log']->info('Query Execution Time:'.$this->query_time);
186
+
187
+
188
+        if($keepResult)
189
+            $this->lastResult = $result;
190
+
191
+        $this->checkError($msg.' Query Failed:' . $sql . '::', $dieOnError);
192
+        return $result;
193
+    }
194 194
 
195 195
     /**
196 196
      * Returns the number of rows affected by the last query
197 197
      * @param $result
198 198
      * @return int
199 199
      */
200
-	public function getAffectedRowCount($result)
201
-	{
202
-		return mysql_affected_rows($this->getDatabase());
203
-	}
204
-
205
-	/**
206
-	 * Returns the number of rows returned by the result
207
-	 *
208
-	 * This function can't be reliably implemented on most DB, do not use it.
209
-	 * @abstract
210
-	 * @deprecated
211
-	 * @param  resource $result
212
-	 * @return int
213
-	 */
214
-	public function getRowCount($result)
215
-	{
216
-	    return mysql_num_rows($result);
217
-	}
218
-
219
-	/**
220
-	 * Disconnects from the database
221
-	 *
222
-	 * Also handles any cleanup needed
223
-	 */
224
-	public function disconnect()
225
-	{
226
-		$GLOBALS['log']->debug('Calling MySQL::disconnect()');
227
-		if(!empty($this->database)){
228
-			$this->freeResult();
229
-			mysql_close($this->database);
230
-			$this->database = null;
231
-		}
232
-	}
233
-
234
-	/**
235
-	 * @see DBManager::freeDbResult()
236
-	 */
237
-	protected function freeDbResult($dbResult)
238
-	{
239
-		if(!empty($dbResult))
240
-			mysql_free_result($dbResult);
241
-	}
242
-
243
-
244
-	/**
245
-	 * @abstract
246
-	 * Check if query has LIMIT clause
247
-	 * Relevant for now only for Mysql
248
-	 * @param string $sql
249
-	 * @return bool
250
-	 */
251
-	protected function hasLimit($sql)
252
-	{
253
-	    return stripos($sql, " limit ") !== false;
254
-	}
255
-
256
-	/**
257
-	 * @see DBManager::limitQuery()
258
-	 */
259
-	public function limitQuery($sql, $start, $count, $dieOnError = false, $msg = '', $execute = true)
260
-	{
200
+    public function getAffectedRowCount($result)
201
+    {
202
+        return mysql_affected_rows($this->getDatabase());
203
+    }
204
+
205
+    /**
206
+     * Returns the number of rows returned by the result
207
+     *
208
+     * This function can't be reliably implemented on most DB, do not use it.
209
+     * @abstract
210
+     * @deprecated
211
+     * @param  resource $result
212
+     * @return int
213
+     */
214
+    public function getRowCount($result)
215
+    {
216
+        return mysql_num_rows($result);
217
+    }
218
+
219
+    /**
220
+     * Disconnects from the database
221
+     *
222
+     * Also handles any cleanup needed
223
+     */
224
+    public function disconnect()
225
+    {
226
+        $GLOBALS['log']->debug('Calling MySQL::disconnect()');
227
+        if(!empty($this->database)){
228
+            $this->freeResult();
229
+            mysql_close($this->database);
230
+            $this->database = null;
231
+        }
232
+    }
233
+
234
+    /**
235
+     * @see DBManager::freeDbResult()
236
+     */
237
+    protected function freeDbResult($dbResult)
238
+    {
239
+        if(!empty($dbResult))
240
+            mysql_free_result($dbResult);
241
+    }
242
+
243
+
244
+    /**
245
+     * @abstract
246
+     * Check if query has LIMIT clause
247
+     * Relevant for now only for Mysql
248
+     * @param string $sql
249
+     * @return bool
250
+     */
251
+    protected function hasLimit($sql)
252
+    {
253
+        return stripos($sql, " limit ") !== false;
254
+    }
255
+
256
+    /**
257
+     * @see DBManager::limitQuery()
258
+     */
259
+    public function limitQuery($sql, $start, $count, $dieOnError = false, $msg = '', $execute = true)
260
+    {
261 261
         $start = (int)$start;
262 262
         $count = (int)$count;
263
-	    if ($start < 0)
264
-			$start = 0;
265
-		$GLOBALS['log']->debug('Limit Query:' . $sql. ' Start: ' .$start . ' count: ' . $count);
266
-
267
-	    $sql = "$sql LIMIT $start,$count";
268
-		$this->lastsql = $sql;
269
-
270
-		if(!empty($GLOBALS['sugar_config']['check_query'])){
271
-			$this->checkQuery($sql);
272
-		}
273
-		if(!$execute) {
274
-			return $sql;
275
-		}
276
-
277
-		return $this->query($sql, $dieOnError, $msg);
278
-	}
279
-
280
-
281
-	/**
282
-	 * @see DBManager::checkQuery()
283
-	 */
284
-	protected function checkQuery($sql, $object_name = false)
285
-	{
286
-		$result   = $this->query('EXPLAIN ' . $sql);
287
-		$badQuery = array();
288
-		while ($row = $this->fetchByAssoc($result)) {
289
-			if (empty($row['table']))
290
-				continue;
291
-			$badQuery[$row['table']] = '';
292
-			if (strtoupper($row['type']) == 'ALL')
293
-				$badQuery[$row['table']]  .=  ' Full Table Scan;';
294
-			if (empty($row['key']))
295
-				$badQuery[$row['table']] .= ' No Index Key Used;';
296
-			if (!empty($row['Extra']) && substr_count($row['Extra'], 'Using filesort') > 0)
297
-				$badQuery[$row['table']] .= ' Using FileSort;';
298
-			if (!empty($row['Extra']) && substr_count($row['Extra'], 'Using temporary') > 0)
299
-				$badQuery[$row['table']] .= ' Using Temporary Table;';
300
-		}
301
-
302
-		if ( empty($badQuery) )
303
-			return true;
304
-
305
-		foreach($badQuery as $table=>$data ){
306
-			if(!empty($data)){
307
-				$warning = ' Table:' . $table . ' Data:' . $data;
308
-				if(!empty($GLOBALS['sugar_config']['check_query_log'])){
309
-					$GLOBALS['log']->fatal($sql);
310
-					$GLOBALS['log']->fatal('CHECK QUERY:' .$warning);
311
-				}
312
-				else{
313
-					$GLOBALS['log']->warn('CHECK QUERY:' .$warning);
314
-				}
315
-			}
316
-		}
317
-
318
-		return false;
319
-	}
320
-
321
-	/**
322
-	 * @see DBManager::get_columns()
323
-	 */
324
-	public function get_columns($tablename)
325
-	{
326
-		//find all unique indexes and primary keys.
327
-		$result = $this->query("DESCRIBE $tablename");
328
-
329
-		$columns = array();
330
-		while (($row=$this->fetchByAssoc($result)) !=null) {
331
-			$name = strtolower($row['Field']);
332
-			$columns[$name]['name']=$name;
333
-			$matches = array();
334
-			preg_match_all('/(\w+)(?:\(([0-9]+,?[0-9]*)\)|)( unsigned)?/i', $row['Type'], $matches);
335
-			$columns[$name]['type']=strtolower($matches[1][0]);
336
-			if ( isset($matches[2][0]) && in_array(strtolower($matches[1][0]),array('varchar','char','varchar2','int','decimal','float')) )
337
-				$columns[$name]['len']=strtolower($matches[2][0]);
338
-			if ( stristr($row['Extra'],'auto_increment') )
339
-				$columns[$name]['auto_increment'] = '1';
340
-			if ($row['Null'] == 'NO' && !stristr($row['Key'],'PRI'))
341
-				$columns[$name]['required'] = 'true';
342
-			if (!empty($row['Default']) )
343
-				$columns[$name]['default'] = $row['Default'];
344
-		}
345
-		return $columns;
346
-	}
347
-
348
-	/**
349
-	 * @see DBManager::getFieldsArray()
350
-	 */
351
-	public function getFieldsArray($result, $make_lower_case=false)
352
-	{
353
-		$field_array = array();
354
-
355
-		if(empty($result))
356
-			return 0;
357
-
358
-		$fields = mysql_num_fields($result);
359
-		for ($i=0; $i < $fields; $i++) {
360
-			$meta = mysql_fetch_field($result, $i);
361
-			if (!$meta)
362
-				return array();
363
-
364
-			if($make_lower_case == true)
365
-				$meta->name = strtolower($meta->name);
366
-
367
-			$field_array[] = $meta->name;
368
-		}
369
-
370
-		return $field_array;
371
-	}
372
-
373
-	/**
374
-	 * @see DBManager::fetchRow()
375
-	 */
376
-	public function fetchRow($result)
377
-	{
378
-		if (empty($result))	return false;
379
-
380
-		return mysql_fetch_assoc($result);
381
-	}
382
-
383
-	/**
384
-	 * @see DBManager::getTablesArray()
385
-	 */
386
-	public function getTablesArray()
387
-	{
388
-		$this->log->debug('Fetching table list');
389
-
390
-		if ($this->getDatabase()) {
391
-			$tables = array();
392
-			$r = $this->query('SHOW TABLES');
393
-			if (!empty($r)) {
394
-				while ($a = $this->fetchByAssoc($r)) {
395
-					$row = array_values($a);
396
-					$tables[]=$row[0];
397
-				}
398
-				return $tables;
399
-			}
400
-		}
401
-
402
-		return false; // no database available
403
-	}
404
-
405
-	/**
406
-	 * @see DBManager::version()
407
-	 */
408
-	public function version()
409
-	{
410
-		return $this->getOne("SELECT version() version");
411
-	}
412
-
413
-	/**
414
-	 * @see DBManager::tableExists()
415
-	 */
416
-	public function tableExists($tableName)
417
-	{
418
-		$this->log->info("tableExists: $tableName");
419
-
420
-		if ($this->getDatabase()) {
421
-			$result = $this->query("SHOW TABLES LIKE ".$this->quoted($tableName));
422
-			if(empty($result)) return false;
423
-			$row = $this->fetchByAssoc($result);
424
-			return !empty($row);
425
-		}
426
-
427
-		return false;
428
-	}
429
-
430
-	/**
431
-	 * Get tables like expression
432
-	 * @param $like string
433
-	 * @return array
434
-	 */
435
-	public function tablesLike($like)
436
-	{
437
-		if ($this->getDatabase()) {
438
-			$tables = array();
439
-			$r = $this->query('SHOW TABLES LIKE '.$this->quoted($like));
440
-			if (!empty($r)) {
441
-				while ($a = $this->fetchByAssoc($r)) {
442
-					$row = array_values($a);
443
-					$tables[]=$row[0];
444
-				}
445
-				return $tables;
446
-			}
447
-		}
448
-		return false;
449
-	}
450
-
451
-	/**
452
-	 * @see DBManager::quote()
453
-	 */
454
-	public function quote($string)
455
-	{
456
-		if(is_array($string)) {
457
-			return $this->arrayQuote($string);
458
-		}
459
-		return mysql_real_escape_string($this->quoteInternal($string), $this->getDatabase());
460
-	}
263
+        if ($start < 0)
264
+            $start = 0;
265
+        $GLOBALS['log']->debug('Limit Query:' . $sql. ' Start: ' .$start . ' count: ' . $count);
266
+
267
+        $sql = "$sql LIMIT $start,$count";
268
+        $this->lastsql = $sql;
269
+
270
+        if(!empty($GLOBALS['sugar_config']['check_query'])){
271
+            $this->checkQuery($sql);
272
+        }
273
+        if(!$execute) {
274
+            return $sql;
275
+        }
276
+
277
+        return $this->query($sql, $dieOnError, $msg);
278
+    }
279
+
280
+
281
+    /**
282
+     * @see DBManager::checkQuery()
283
+     */
284
+    protected function checkQuery($sql, $object_name = false)
285
+    {
286
+        $result   = $this->query('EXPLAIN ' . $sql);
287
+        $badQuery = array();
288
+        while ($row = $this->fetchByAssoc($result)) {
289
+            if (empty($row['table']))
290
+                continue;
291
+            $badQuery[$row['table']] = '';
292
+            if (strtoupper($row['type']) == 'ALL')
293
+                $badQuery[$row['table']]  .=  ' Full Table Scan;';
294
+            if (empty($row['key']))
295
+                $badQuery[$row['table']] .= ' No Index Key Used;';
296
+            if (!empty($row['Extra']) && substr_count($row['Extra'], 'Using filesort') > 0)
297
+                $badQuery[$row['table']] .= ' Using FileSort;';
298
+            if (!empty($row['Extra']) && substr_count($row['Extra'], 'Using temporary') > 0)
299
+                $badQuery[$row['table']] .= ' Using Temporary Table;';
300
+        }
301
+
302
+        if ( empty($badQuery) )
303
+            return true;
304
+
305
+        foreach($badQuery as $table=>$data ){
306
+            if(!empty($data)){
307
+                $warning = ' Table:' . $table . ' Data:' . $data;
308
+                if(!empty($GLOBALS['sugar_config']['check_query_log'])){
309
+                    $GLOBALS['log']->fatal($sql);
310
+                    $GLOBALS['log']->fatal('CHECK QUERY:' .$warning);
311
+                }
312
+                else{
313
+                    $GLOBALS['log']->warn('CHECK QUERY:' .$warning);
314
+                }
315
+            }
316
+        }
317
+
318
+        return false;
319
+    }
320
+
321
+    /**
322
+     * @see DBManager::get_columns()
323
+     */
324
+    public function get_columns($tablename)
325
+    {
326
+        //find all unique indexes and primary keys.
327
+        $result = $this->query("DESCRIBE $tablename");
328
+
329
+        $columns = array();
330
+        while (($row=$this->fetchByAssoc($result)) !=null) {
331
+            $name = strtolower($row['Field']);
332
+            $columns[$name]['name']=$name;
333
+            $matches = array();
334
+            preg_match_all('/(\w+)(?:\(([0-9]+,?[0-9]*)\)|)( unsigned)?/i', $row['Type'], $matches);
335
+            $columns[$name]['type']=strtolower($matches[1][0]);
336
+            if ( isset($matches[2][0]) && in_array(strtolower($matches[1][0]),array('varchar','char','varchar2','int','decimal','float')) )
337
+                $columns[$name]['len']=strtolower($matches[2][0]);
338
+            if ( stristr($row['Extra'],'auto_increment') )
339
+                $columns[$name]['auto_increment'] = '1';
340
+            if ($row['Null'] == 'NO' && !stristr($row['Key'],'PRI'))
341
+                $columns[$name]['required'] = 'true';
342
+            if (!empty($row['Default']) )
343
+                $columns[$name]['default'] = $row['Default'];
344
+        }
345
+        return $columns;
346
+    }
347
+
348
+    /**
349
+     * @see DBManager::getFieldsArray()
350
+     */
351
+    public function getFieldsArray($result, $make_lower_case=false)
352
+    {
353
+        $field_array = array();
354
+
355
+        if(empty($result))
356
+            return 0;
357
+
358
+        $fields = mysql_num_fields($result);
359
+        for ($i=0; $i < $fields; $i++) {
360
+            $meta = mysql_fetch_field($result, $i);
361
+            if (!$meta)
362
+                return array();
363
+
364
+            if($make_lower_case == true)
365
+                $meta->name = strtolower($meta->name);
366
+
367
+            $field_array[] = $meta->name;
368
+        }
369
+
370
+        return $field_array;
371
+    }
372
+
373
+    /**
374
+     * @see DBManager::fetchRow()
375
+     */
376
+    public function fetchRow($result)
377
+    {
378
+        if (empty($result))	return false;
379
+
380
+        return mysql_fetch_assoc($result);
381
+    }
382
+
383
+    /**
384
+     * @see DBManager::getTablesArray()
385
+     */
386
+    public function getTablesArray()
387
+    {
388
+        $this->log->debug('Fetching table list');
389
+
390
+        if ($this->getDatabase()) {
391
+            $tables = array();
392
+            $r = $this->query('SHOW TABLES');
393
+            if (!empty($r)) {
394
+                while ($a = $this->fetchByAssoc($r)) {
395
+                    $row = array_values($a);
396
+                    $tables[]=$row[0];
397
+                }
398
+                return $tables;
399
+            }
400
+        }
401
+
402
+        return false; // no database available
403
+    }
404
+
405
+    /**
406
+     * @see DBManager::version()
407
+     */
408
+    public function version()
409
+    {
410
+        return $this->getOne("SELECT version() version");
411
+    }
412
+
413
+    /**
414
+     * @see DBManager::tableExists()
415
+     */
416
+    public function tableExists($tableName)
417
+    {
418
+        $this->log->info("tableExists: $tableName");
419
+
420
+        if ($this->getDatabase()) {
421
+            $result = $this->query("SHOW TABLES LIKE ".$this->quoted($tableName));
422
+            if(empty($result)) return false;
423
+            $row = $this->fetchByAssoc($result);
424
+            return !empty($row);
425
+        }
426
+
427
+        return false;
428
+    }
429
+
430
+    /**
431
+     * Get tables like expression
432
+     * @param $like string
433
+     * @return array
434
+     */
435
+    public function tablesLike($like)
436
+    {
437
+        if ($this->getDatabase()) {
438
+            $tables = array();
439
+            $r = $this->query('SHOW TABLES LIKE '.$this->quoted($like));
440
+            if (!empty($r)) {
441
+                while ($a = $this->fetchByAssoc($r)) {
442
+                    $row = array_values($a);
443
+                    $tables[]=$row[0];
444
+                }
445
+                return $tables;
446
+            }
447
+        }
448
+        return false;
449
+    }
450
+
451
+    /**
452
+     * @see DBManager::quote()
453
+     */
454
+    public function quote($string)
455
+    {
456
+        if(is_array($string)) {
457
+            return $this->arrayQuote($string);
458
+        }
459
+        return mysql_real_escape_string($this->quoteInternal($string), $this->getDatabase());
460
+    }
461 461
 
462 462
     /**
463 463
      * @see DBManager::quoteIdentifier()
@@ -467,272 +467,272 @@  discard block
 block discarded – undo
467 467
         return '`'.$string.'`';
468 468
     }
469 469
 
470
-	/**
471
-	 * @see DBManager::connect()
472
-	 */
473
-	public function connect(array $configOptions = null, $dieOnError = false)
474
-	{
475
-		global $sugar_config;
476
-
477
-		if(is_null($configOptions))
478
-			$configOptions = $sugar_config['dbconfig'];
479
-
480
-		if ($this->getOption('persistent')) {
481
-			$this->database = @mysql_pconnect(
482
-				$configOptions['db_host_name'],
483
-				$configOptions['db_user_name'],
484
-				$configOptions['db_password']
485
-				);
486
-		}
487
-
488
-		if (!$this->database) {
489
-			$this->database = mysql_connect(
490
-					$configOptions['db_host_name'],
491
-					$configOptions['db_user_name'],
492
-					$configOptions['db_password']
493
-					);
494
-			if(empty($this->database)) {
495
-				$GLOBALS['log']->fatal("Could not connect to server ".$configOptions['db_host_name']." as ".$configOptions['db_user_name'].":".mysql_error());
496
-				if($dieOnError) {
497
-					if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
498
-						sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
499
-					} else {
500
-						sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
501
-					}
502
-				} else {
503
-					return false;
504
-				}
505
-			}
506
-			// Do not pass connection information because we have not connected yet
507
-			if($this->database  && $this->getOption('persistent')){
508
-				$_SESSION['administrator_error'] = "<b>Severe Performance Degradation: Persistent Database Connections "
509
-					. "not working.  Please set \$sugar_config['dbconfigoption']['persistent'] to false "
510
-					. "in your config.php file</b>";
511
-			}
512
-		}
513
-		if(!empty($configOptions['db_name']) && !@mysql_select_db($configOptions['db_name'])) {
514
-			$GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}: " . mysql_error($this->database));
515
-			if($dieOnError) {
516
-				sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
517
-			} else {
518
-				return false;
519
-			}
520
-		}
521
-
522
-		// cn: using direct calls to prevent this from spamming the Logs
523
-	    mysql_query("SET CHARACTER SET utf8", $this->database);
524
-	    $names = "SET NAMES 'utf8'";
525
-	    $collation = $this->getOption('collation');
526
-	    if(!empty($collation)) {
527
-	        $names .= " COLLATE '$collation'";
528
-		}
529
-	    mysql_query($names, $this->database);
530
-
531
-		if(!$this->checkError('Could Not Connect:', $dieOnError))
532
-			$GLOBALS['log']->info("connected to db");
533
-		$this->connectOptions = $configOptions;
534
-
535
-		$GLOBALS['log']->info("Connect:".$this->database);
536
-		return true;
537
-	}
538
-
539
-	/**
540
-	 * @see DBManager::repairTableParams()
541
-	 *
542
-	 * For MySQL, we can write the ALTER TABLE statement all in one line, which speeds things
543
-	 * up quite a bit. So here, we'll parse the returned SQL into a single ALTER TABLE command.
544
-	 */
545
-	public function repairTableParams($tablename, $fielddefs, $indices, $execute = true, $engine = null)
546
-	{
547
-		$sql = parent::repairTableParams($tablename,$fielddefs,$indices,false,$engine);
548
-
549
-		if ( $sql == '' )
550
-			return '';
551
-
552
-		if ( stristr($sql,'create table') )
553
-		{
554
-			if ($execute) {
555
-				$msg = "Error creating table: ".$tablename. ":";
556
-				$this->query($sql,true,$msg);
557
-			}
558
-			return $sql;
559
-		}
560
-
561
-		// first, parse out all the comments
562
-		$match = array();
563
-		preg_match_all('!/\*.*?\*/!is', $sql, $match);
564
-		$commentBlocks = $match[0];
565
-		$sql = preg_replace('!/\*.*?\*/!is','', $sql);
566
-
567
-		// now, we should only have alter table statements
568
-		// let's replace the 'alter table name' part with a comma
569
-		$sql = preg_replace("!alter table $tablename!is",', ', $sql);
570
-
571
-		// re-add it at the beginning
572
-		$sql = substr_replace($sql,'',strpos($sql,','),1);
573
-		$sql = str_replace(";","",$sql);
574
-		$sql = str_replace("\n","",$sql);
575
-		$sql = "ALTER TABLE $tablename $sql";
576
-
577
-		if ( $execute )
578
-			$this->query($sql,'Error with MySQL repair table');
579
-
580
-		// and re-add the comments at the beginning
581
-		$sql = implode("\n",$commentBlocks) . "\n". $sql . "\n";
582
-
583
-		return $sql;
584
-	}
585
-
586
-	/**
587
-	 * @see DBManager::convert()
588
-	 */
589
-	public function convert($string, $type, array $additional_parameters = array())
590
-	{
591
-		$all_parameters = $additional_parameters;
592
-		if(is_array($string)) {
593
-			$all_parameters = array_merge($string, $all_parameters);
594
-		} elseif (!is_null($string)) {
595
-			array_unshift($all_parameters, $string);
596
-		}
597
-		$all_strings = implode(',', $all_parameters);
598
-
599
-		switch (strtolower($type)) {
600
-			case 'today':
601
-				return "CURDATE()";
602
-			case 'left':
603
-				return "LEFT($all_strings)";
604
-			case 'date_format':
605
-				if(empty($additional_parameters)) {
606
-					return "DATE_FORMAT($string,'%Y-%m-%d')";
607
-				} else {
608
-					$format = $additional_parameters[0];
609
-					if($format[0] != "'") {
610
-						$format = $this->quoted($format);
611
-					}
612
-					return "DATE_FORMAT($string,$format)";
613
-				}
614
-			case 'ifnull':
615
-				if(empty($additional_parameters) && !strstr($all_strings, ",")) {
616
-					$all_strings .= ",''";
617
-				}
618
-				return "IFNULL($all_strings)";
619
-			case 'concat':
620
-				return "CONCAT($all_strings)";
621
-			case 'quarter':
622
-					return "QUARTER($string)";
623
-			case "length":
624
-					return "LENGTH($string)";
625
-			case 'month':
626
-					return "MONTH($string)";
627
-			case 'add_date':
628
-					return "DATE_ADD($string, INTERVAL {$additional_parameters[0]} {$additional_parameters[1]})";
629
-			case 'add_time':
630
-					return "DATE_ADD($string, INTERVAL + CONCAT({$additional_parameters[0]}, ':', {$additional_parameters[1]}) HOUR_MINUTE)";
470
+    /**
471
+     * @see DBManager::connect()
472
+     */
473
+    public function connect(array $configOptions = null, $dieOnError = false)
474
+    {
475
+        global $sugar_config;
476
+
477
+        if(is_null($configOptions))
478
+            $configOptions = $sugar_config['dbconfig'];
479
+
480
+        if ($this->getOption('persistent')) {
481
+            $this->database = @mysql_pconnect(
482
+                $configOptions['db_host_name'],
483
+                $configOptions['db_user_name'],
484
+                $configOptions['db_password']
485
+                );
486
+        }
487
+
488
+        if (!$this->database) {
489
+            $this->database = mysql_connect(
490
+                    $configOptions['db_host_name'],
491
+                    $configOptions['db_user_name'],
492
+                    $configOptions['db_password']
493
+                    );
494
+            if(empty($this->database)) {
495
+                $GLOBALS['log']->fatal("Could not connect to server ".$configOptions['db_host_name']." as ".$configOptions['db_user_name'].":".mysql_error());
496
+                if($dieOnError) {
497
+                    if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
498
+                        sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
499
+                    } else {
500
+                        sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
501
+                    }
502
+                } else {
503
+                    return false;
504
+                }
505
+            }
506
+            // Do not pass connection information because we have not connected yet
507
+            if($this->database  && $this->getOption('persistent')){
508
+                $_SESSION['administrator_error'] = "<b>Severe Performance Degradation: Persistent Database Connections "
509
+                    . "not working.  Please set \$sugar_config['dbconfigoption']['persistent'] to false "
510
+                    . "in your config.php file</b>";
511
+            }
512
+        }
513
+        if(!empty($configOptions['db_name']) && !@mysql_select_db($configOptions['db_name'])) {
514
+            $GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}: " . mysql_error($this->database));
515
+            if($dieOnError) {
516
+                sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
517
+            } else {
518
+                return false;
519
+            }
520
+        }
521
+
522
+        // cn: using direct calls to prevent this from spamming the Logs
523
+        mysql_query("SET CHARACTER SET utf8", $this->database);
524
+        $names = "SET NAMES 'utf8'";
525
+        $collation = $this->getOption('collation');
526
+        if(!empty($collation)) {
527
+            $names .= " COLLATE '$collation'";
528
+        }
529
+        mysql_query($names, $this->database);
530
+
531
+        if(!$this->checkError('Could Not Connect:', $dieOnError))
532
+            $GLOBALS['log']->info("connected to db");
533
+        $this->connectOptions = $configOptions;
534
+
535
+        $GLOBALS['log']->info("Connect:".$this->database);
536
+        return true;
537
+    }
538
+
539
+    /**
540
+     * @see DBManager::repairTableParams()
541
+     *
542
+     * For MySQL, we can write the ALTER TABLE statement all in one line, which speeds things
543
+     * up quite a bit. So here, we'll parse the returned SQL into a single ALTER TABLE command.
544
+     */
545
+    public function repairTableParams($tablename, $fielddefs, $indices, $execute = true, $engine = null)
546
+    {
547
+        $sql = parent::repairTableParams($tablename,$fielddefs,$indices,false,$engine);
548
+
549
+        if ( $sql == '' )
550
+            return '';
551
+
552
+        if ( stristr($sql,'create table') )
553
+        {
554
+            if ($execute) {
555
+                $msg = "Error creating table: ".$tablename. ":";
556
+                $this->query($sql,true,$msg);
557
+            }
558
+            return $sql;
559
+        }
560
+
561
+        // first, parse out all the comments
562
+        $match = array();
563
+        preg_match_all('!/\*.*?\*/!is', $sql, $match);
564
+        $commentBlocks = $match[0];
565
+        $sql = preg_replace('!/\*.*?\*/!is','', $sql);
566
+
567
+        // now, we should only have alter table statements
568
+        // let's replace the 'alter table name' part with a comma
569
+        $sql = preg_replace("!alter table $tablename!is",', ', $sql);
570
+
571
+        // re-add it at the beginning
572
+        $sql = substr_replace($sql,'',strpos($sql,','),1);
573
+        $sql = str_replace(";","",$sql);
574
+        $sql = str_replace("\n","",$sql);
575
+        $sql = "ALTER TABLE $tablename $sql";
576
+
577
+        if ( $execute )
578
+            $this->query($sql,'Error with MySQL repair table');
579
+
580
+        // and re-add the comments at the beginning
581
+        $sql = implode("\n",$commentBlocks) . "\n". $sql . "\n";
582
+
583
+        return $sql;
584
+    }
585
+
586
+    /**
587
+     * @see DBManager::convert()
588
+     */
589
+    public function convert($string, $type, array $additional_parameters = array())
590
+    {
591
+        $all_parameters = $additional_parameters;
592
+        if(is_array($string)) {
593
+            $all_parameters = array_merge($string, $all_parameters);
594
+        } elseif (!is_null($string)) {
595
+            array_unshift($all_parameters, $string);
596
+        }
597
+        $all_strings = implode(',', $all_parameters);
598
+
599
+        switch (strtolower($type)) {
600
+            case 'today':
601
+                return "CURDATE()";
602
+            case 'left':
603
+                return "LEFT($all_strings)";
604
+            case 'date_format':
605
+                if(empty($additional_parameters)) {
606
+                    return "DATE_FORMAT($string,'%Y-%m-%d')";
607
+                } else {
608
+                    $format = $additional_parameters[0];
609
+                    if($format[0] != "'") {
610
+                        $format = $this->quoted($format);
611
+                    }
612
+                    return "DATE_FORMAT($string,$format)";
613
+                }
614
+            case 'ifnull':
615
+                if(empty($additional_parameters) && !strstr($all_strings, ",")) {
616
+                    $all_strings .= ",''";
617
+                }
618
+                return "IFNULL($all_strings)";
619
+            case 'concat':
620
+                return "CONCAT($all_strings)";
621
+            case 'quarter':
622
+                    return "QUARTER($string)";
623
+            case "length":
624
+                    return "LENGTH($string)";
625
+            case 'month':
626
+                    return "MONTH($string)";
627
+            case 'add_date':
628
+                    return "DATE_ADD($string, INTERVAL {$additional_parameters[0]} {$additional_parameters[1]})";
629
+            case 'add_time':
630
+                    return "DATE_ADD($string, INTERVAL + CONCAT({$additional_parameters[0]}, ':', {$additional_parameters[1]}) HOUR_MINUTE)";
631 631
             case 'add_tz_offset' :
632 632
                 $getUserUTCOffset = $GLOBALS['timedate']->getUserUTCOffset();
633 633
                 $operation = $getUserUTCOffset < 0 ? '-' : '+';
634 634
                 return $string . ' ' . $operation . ' INTERVAL ' . abs($getUserUTCOffset) . ' MINUTE';
635 635
             case 'avg':
636 636
                 return "avg($string)";
637
-		}
638
-
639
-		return $string;
640
-	}
641
-
642
-	/**
643
-	 * (non-PHPdoc)
644
-	 * @see DBManager::fromConvert()
645
-	 */
646
-	public function fromConvert($string, $type)
647
-	{
648
-		return $string;
649
-	}
650
-
651
-	/**
652
-	 * Returns the name of the engine to use or null if we are to use the default
653
-	 *
654
-	 * @param  object $bean SugarBean instance
655
-	 * @return string
656
-	 */
657
-	protected function getEngine($bean)
658
-	{
659
-		global $dictionary;
660
-		$engine = null;
661
-		if (isset($dictionary[$bean->getObjectName()]['engine'])) {
662
-			$engine = $dictionary[$bean->getObjectName()]['engine'];
663
-		}
664
-		return $engine;
665
-	}
666
-
667
-	/**
668
-	 * Returns true if the engine given is enabled in the backend
669
-	 *
670
-	 * @param  string $engine
671
-	 * @return bool
672
-	 */
673
-	protected function isEngineEnabled($engine)
674
-	{
675
-		if(!is_string($engine)) return false;
676
-
677
-		$engine = strtoupper($engine);
678
-
679
-		$r = $this->query("SHOW ENGINES");
680
-
681
-		while ( $row = $this->fetchByAssoc($r) )
682
-			if ( strtoupper($row['Engine']) == $engine )
683
-				return ($row['Support']=='YES' || $row['Support']=='DEFAULT');
684
-
685
-		return false;
686
-	}
687
-
688
-	/**
689
-	 * @see DBManager::createTableSQL()
690
-	 */
691
-	public function createTableSQL(SugarBean $bean)
692
-	{
693
-		$tablename = $bean->getTableName();
694
-		$fieldDefs = $bean->getFieldDefinitions();
695
-		$indices   = $bean->getIndices();
696
-		$engine    = $this->getEngine($bean);
697
-		return $this->createTableSQLParams($tablename, $fieldDefs, $indices, $engine);
698
-	}
699
-
700
-	/**
701
-	 * Generates sql for create table statement for a bean.
702
-	 *
703
-	 * @param  string $tablename
704
-	 * @param  array  $fieldDefs
705
-	 * @param  array  $indices
706
-	 * @param  string $engine optional, MySQL engine to use
707
-	 * @return string SQL Create Table statement
708
-	*/
709
-	public function createTableSQLParams($tablename, $fieldDefs, $indices, $engine = null)
710
-	{
711
-		if ( empty($engine) && isset($fieldDefs['engine']))
712
-			$engine = $fieldDefs['engine'];
713
-		if ( !$this->isEngineEnabled($engine) )
714
-			$engine = '';
715
-
716
-		$columns = $this->columnSQLRep($fieldDefs, false, $tablename);
717
-		if (empty($columns))
718
-			return false;
719
-
720
-		$keys = $this->keysSQL($indices);
721
-		if (!empty($keys))
722
-			$keys = ",$keys";
723
-
724
-		// cn: bug 9873 - module tables do not get created in utf8 with assoc collation
725
-		$collation = $this->getOption('collation');
726
-		if(empty($collation)) {
727
-		    $collation = 'utf8_general_ci';
728
-		}
729
-		$sql = "CREATE TABLE $tablename ($columns $keys) CHARACTER SET utf8 COLLATE $collation";
730
-
731
-		if (!empty($engine))
732
-			$sql.= " ENGINE=$engine";
733
-
734
-		return $sql;
735
-	}
637
+        }
638
+
639
+        return $string;
640
+    }
641
+
642
+    /**
643
+     * (non-PHPdoc)
644
+     * @see DBManager::fromConvert()
645
+     */
646
+    public function fromConvert($string, $type)
647
+    {
648
+        return $string;
649
+    }
650
+
651
+    /**
652
+     * Returns the name of the engine to use or null if we are to use the default
653
+     *
654
+     * @param  object $bean SugarBean instance
655
+     * @return string
656
+     */
657
+    protected function getEngine($bean)
658
+    {
659
+        global $dictionary;
660
+        $engine = null;
661
+        if (isset($dictionary[$bean->getObjectName()]['engine'])) {
662
+            $engine = $dictionary[$bean->getObjectName()]['engine'];
663
+        }
664
+        return $engine;
665
+    }
666
+
667
+    /**
668
+     * Returns true if the engine given is enabled in the backend
669
+     *
670
+     * @param  string $engine
671
+     * @return bool
672
+     */
673
+    protected function isEngineEnabled($engine)
674
+    {
675
+        if(!is_string($engine)) return false;
676
+
677
+        $engine = strtoupper($engine);
678
+
679
+        $r = $this->query("SHOW ENGINES");
680
+
681
+        while ( $row = $this->fetchByAssoc($r) )
682
+            if ( strtoupper($row['Engine']) == $engine )
683
+                return ($row['Support']=='YES' || $row['Support']=='DEFAULT');
684
+
685
+        return false;
686
+    }
687
+
688
+    /**
689
+     * @see DBManager::createTableSQL()
690
+     */
691
+    public function createTableSQL(SugarBean $bean)
692
+    {
693
+        $tablename = $bean->getTableName();
694
+        $fieldDefs = $bean->getFieldDefinitions();
695
+        $indices   = $bean->getIndices();
696
+        $engine    = $this->getEngine($bean);
697
+        return $this->createTableSQLParams($tablename, $fieldDefs, $indices, $engine);
698
+    }
699
+
700
+    /**
701
+     * Generates sql for create table statement for a bean.
702
+     *
703
+     * @param  string $tablename
704
+     * @param  array  $fieldDefs
705
+     * @param  array  $indices
706
+     * @param  string $engine optional, MySQL engine to use
707
+     * @return string SQL Create Table statement
708
+     */
709
+    public function createTableSQLParams($tablename, $fieldDefs, $indices, $engine = null)
710
+    {
711
+        if ( empty($engine) && isset($fieldDefs['engine']))
712
+            $engine = $fieldDefs['engine'];
713
+        if ( !$this->isEngineEnabled($engine) )
714
+            $engine = '';
715
+
716
+        $columns = $this->columnSQLRep($fieldDefs, false, $tablename);
717
+        if (empty($columns))
718
+            return false;
719
+
720
+        $keys = $this->keysSQL($indices);
721
+        if (!empty($keys))
722
+            $keys = ",$keys";
723
+
724
+        // cn: bug 9873 - module tables do not get created in utf8 with assoc collation
725
+        $collation = $this->getOption('collation');
726
+        if(empty($collation)) {
727
+            $collation = 'utf8_general_ci';
728
+        }
729
+        $sql = "CREATE TABLE $tablename ($columns $keys) CHARACTER SET utf8 COLLATE $collation";
730
+
731
+        if (!empty($engine))
732
+            $sql.= " ENGINE=$engine";
733
+
734
+        return $sql;
735
+    }
736 736
 
737 737
     /**
738 738
      * Does this type represent text (i.e., non-varchar) value?
@@ -744,745 +744,745 @@  discard block
 block discarded – undo
744 744
         return in_array($type, array('blob','text','longblob', 'longtext'));
745 745
     }
746 746
 
747
-	/**
748
-	 * @see DBManager::oneColumnSQLRep()
749
-	 */
750
-	protected function oneColumnSQLRep($fieldDef, $ignoreRequired = false, $table = '', $return_as_array = false)
751
-	{
752
-		// always return as array for post-processing
753
-		$ref = parent::oneColumnSQLRep($fieldDef, $ignoreRequired, $table, true);
747
+    /**
748
+     * @see DBManager::oneColumnSQLRep()
749
+     */
750
+    protected function oneColumnSQLRep($fieldDef, $ignoreRequired = false, $table = '', $return_as_array = false)
751
+    {
752
+        // always return as array for post-processing
753
+        $ref = parent::oneColumnSQLRep($fieldDef, $ignoreRequired, $table, true);
754 754
 
755
-		if ( $ref['colType'] == 'int' && !empty($fieldDef['len']) ) {
756
-			$ref['colType'] .= "(".$fieldDef['len'].")";
757
-		}
755
+        if ( $ref['colType'] == 'int' && !empty($fieldDef['len']) ) {
756
+            $ref['colType'] .= "(".$fieldDef['len'].")";
757
+        }
758 758
 
759
-		// bug 22338 - don't set a default value on text or blob fields
760
-		if ( isset($ref['default']) &&
759
+        // bug 22338 - don't set a default value on text or blob fields
760
+        if ( isset($ref['default']) &&
761 761
             in_array($ref['colBaseType'], array('text', 'blob', 'longtext', 'longblob')))
762
-			    $ref['default'] = '';
763
-
764
-		if ( $return_as_array )
765
-			return $ref;
766
-		else
767
-			return "{$ref['name']} {$ref['colType']} {$ref['default']} {$ref['required']} {$ref['auto_increment']}";
768
-	}
769
-
770
-	/**
771
-	 * @see DBManager::changeColumnSQL()
772
-	 */
773
-	protected function changeColumnSQL($tablename, $fieldDefs, $action, $ignoreRequired = false)
774
-	{
775
-		$columns = array();
776
-		if ($this->isFieldArray($fieldDefs)){
777
-			foreach ($fieldDefs as $def){
778
-				if ($action == 'drop')
779
-					$columns[] = $def['name'];
780
-				else
781
-					$columns[] = $this->oneColumnSQLRep($def, $ignoreRequired);
782
-			}
783
-		} else {
784
-			if ($action == 'drop')
785
-				$columns[] = $fieldDefs['name'];
786
-		else
787
-			$columns[] = $this->oneColumnSQLRep($fieldDefs);
788
-		}
789
-
790
-		return "ALTER TABLE $tablename $action COLUMN ".implode(",$action column ", $columns);
791
-	}
792
-
793
-	/**
794
-	 * Generates SQL for key specification inside CREATE TABLE statement
795
-	 *
796
-	 * The passes array is an array of field definitions or a field definition
797
-	 * itself. The keys generated will be either primary, foreign, unique, index
798
-	 * or none at all depending on the setting of the "key" parameter of a field definition
799
-	 *
800
-	 * @param  array  $indices
801
-	 * @param  bool   $alter_table
802
-	 * @param  string $alter_action
803
-	 * @return string SQL Statement
804
-	 */
805
-	protected function keysSQL($indices, $alter_table = false, $alter_action = '')
806
-	{
807
-	// check if the passed value is an array of fields.
808
-	// if not, convert it into an array
809
-	if (!$this->isFieldArray($indices))
810
-		$indices[] = $indices;
811
-
812
-	$columns = array();
813
-	foreach ($indices as $index) {
814
-		if(!empty($index['db']) && $index['db'] != $this->dbType)
815
-			continue;
816
-		if (isset($index['source']) && $index['source'] != 'db')
817
-			continue;
818
-
819
-		$type = $index['type'];
820
-		$name = $index['name'];
821
-
822
-		if (is_array($index['fields']))
823
-			$fields = implode(", ", $index['fields']);
824
-		else
825
-			$fields = $index['fields'];
826
-
827
-		switch ($type) {
828
-		case 'unique':
829
-			$columns[] = " UNIQUE $name ($fields)";
830
-			break;
831
-		case 'primary':
832
-			$columns[] = " PRIMARY KEY ($fields)";
833
-			break;
834
-		case 'index':
835
-		case 'foreign':
836
-		case 'clustered':
837
-		case 'alternate_key':
838
-			/**
839
-				* @todo here it is assumed that the primary key of the foreign
840
-				* table will always be named 'id'. It must be noted though
841
-				* that this can easily be fixed by referring to db dictionary
842
-				* to find the correct primary field name
843
-				*/
844
-			if ( $alter_table )
845
-				$columns[] = " INDEX $name ($fields)";
846
-			else
847
-				$columns[] = " KEY $name ($fields)";
848
-			break;
849
-		case 'fulltext':
850
-			if ($this->full_text_indexing_installed())
851
-				$columns[] = " FULLTEXT ($fields)";
852
-			else
853
-				$GLOBALS['log']->debug('MYISAM engine is not available/enabled, full-text indexes will be skipped. Skipping:',$name);
854
-			break;
855
-		}
856
-	}
857
-	$columns = implode(", $alter_action ", $columns);
858
-	if(!empty($alter_action)){
859
-		$columns = $alter_action . ' '. $columns;
860
-	}
861
-	return $columns;
862
-	}
863
-
864
-	/**
865
-	 * @see DBManager::setAutoIncrement()
866
-	 */
867
-	protected function setAutoIncrement($table, $field_name)
868
-	{
869
-		return "auto_increment";
870
-	}
871
-
872
-	/**
873
-	 * Sets the next auto-increment value of a column to a specific value.
874
-	 *
875
-	 * @param  string $table tablename
876
-	 * @param  string $field_name
877
-	 */
878
-	public function setAutoIncrementStart($table, $field_name, $start_value)
879
-	{
880
-		$start_value = (int)$start_value;
881
-		return $this->query( "ALTER TABLE $table AUTO_INCREMENT = $start_value;");
882
-	}
883
-
884
-	/**
885
-	 * Returns the next value for an auto increment
886
-	 *
887
-	 * @param  string $table tablename
888
-	 * @param  string $field_name
889
-	 * @return string
890
-	 */
891
-	public function getAutoIncrement($table, $field_name)
892
-	{
893
-		$result = $this->query("SHOW TABLE STATUS LIKE '$table'");
894
-		$row = $this->fetchByAssoc($result);
895
-		if (!empty($row['Auto_increment']))
896
-			return $row['Auto_increment'];
897
-
898
-		return "";
899
-	}
900
-
901
-	/**
902
-	 * @see DBManager::get_indices()
903
-	 */
904
-	public function get_indices($tablename)
905
-	{
906
-		//find all unique indexes and primary keys.
907
-		$result = $this->query("SHOW INDEX FROM $tablename");
908
-
909
-		$indices = array();
910
-		while (($row=$this->fetchByAssoc($result)) !=null) {
911
-			$index_type='index';
912
-			if ($row['Key_name'] =='PRIMARY') {
913
-				$index_type='primary';
914
-			}
915
-			elseif ( $row['Non_unique'] == '0' ) {
916
-				$index_type='unique';
917
-			}
918
-			$name = strtolower($row['Key_name']);
919
-			$indices[$name]['name']=$name;
920
-			$indices[$name]['type']=$index_type;
921
-			$indices[$name]['fields'][]=strtolower($row['Column_name']);
922
-		}
923
-		return $indices;
924
-	}
925
-
926
-	/**
927
-	 * @see DBManager::add_drop_constraint()
928
-	 */
929
-	public function add_drop_constraint($table, $definition, $drop = false)
930
-	{
931
-		$type         = $definition['type'];
932
-		$fields       = implode(',',$definition['fields']);
933
-		$name         = $definition['name'];
934
-		$sql          = '';
935
-
936
-		switch ($type){
937
-		// generic indices
938
-		case 'index':
939
-		case 'alternate_key':
940
-		case 'clustered':
941
-			if ($drop)
942
-				$sql = "ALTER TABLE {$table} DROP INDEX {$name} ";
943
-			else
944
-				$sql = "ALTER TABLE {$table} ADD INDEX {$name} ({$fields})";
945
-			break;
946
-		// constraints as indices
947
-		case 'unique':
948
-			if ($drop)
949
-				$sql = "ALTER TABLE {$table} DROP INDEX $name";
950
-			else
951
-				$sql = "ALTER TABLE {$table} ADD CONSTRAINT UNIQUE {$name} ({$fields})";
952
-			break;
953
-		case 'primary':
954
-			if ($drop)
955
-				$sql = "ALTER TABLE {$table} DROP PRIMARY KEY";
956
-			else
957
-				$sql = "ALTER TABLE {$table} ADD CONSTRAINT PRIMARY KEY ({$fields})";
958
-			break;
959
-		case 'foreign':
960
-			if ($drop)
961
-				$sql = "ALTER TABLE {$table} DROP FOREIGN KEY ({$fields})";
962
-			else
963
-				$sql = "ALTER TABLE {$table} ADD CONSTRAINT FOREIGN KEY {$name} ({$fields}) REFERENCES {$definition['foreignTable']}({$definition['foreignField']})";
964
-			break;
965
-		}
966
-		return $sql;
967
-	}
968
-
969
-	/**
970
-	 * Runs a query and returns a single row
971
-	 *
972
-	 * @param  string   $sql        SQL Statement to execute
973
-	 * @param  bool     $dieOnError True if we want to call die if the query returns errors
974
-	 * @param  string   $msg        Message to log if error occurs
975
-	 * @param  bool     $suppress   Message to log if error occurs
976
-	 * @return array    single row from the query
977
-	 */
978
-	public function fetchOne($sql, $dieOnError = false, $msg = '', $suppress = false)
979
-	{
980
-		if(stripos($sql, ' LIMIT ') === false) {
981
-			// little optimization to just fetch one row
982
-			$sql .= " LIMIT 0,1";
983
-		}
984
-		return parent::fetchOne($sql, $dieOnError, $msg, $suppress);
985
-	}
986
-
987
-	/**
988
-	 * @see DBManager::full_text_indexing_installed()
989
-	 */
990
-	public function full_text_indexing_installed($dbname = null)
991
-	{
992
-		return $this->isEngineEnabled('MyISAM');
993
-	}
994
-
995
-	/**
996
-	 * @see DBManager::massageFieldDef()
997
-	 */
998
-	public function massageFieldDef(&$fieldDef, $tablename)
999
-	{
1000
-		parent::massageFieldDef($fieldDef,$tablename);
1001
-
1002
-		if ( isset($fieldDef['default']) &&
1003
-			($fieldDef['dbType'] == 'text'
1004
-				|| $fieldDef['dbType'] == 'blob'
1005
-				|| $fieldDef['dbType'] == 'longtext'
1006
-				|| $fieldDef['dbType'] == 'longblob' ))
1007
-			unset($fieldDef['default']);
1008
-		if ($fieldDef['dbType'] == 'uint')
1009
-			$fieldDef['len'] = '10';
1010
-		if ($fieldDef['dbType'] == 'ulong')
1011
-			$fieldDef['len'] = '20';
1012
-		if ($fieldDef['dbType'] == 'bool')
1013
-			$fieldDef['type'] = 'tinyint';
1014
-		if ($fieldDef['dbType'] == 'bool' && empty($fieldDef['default']) )
1015
-			$fieldDef['default'] = '0';
1016
-		if (($fieldDef['dbType'] == 'varchar' || $fieldDef['dbType'] == 'enum') && empty($fieldDef['len']) )
1017
-			$fieldDef['len'] = '255';
1018
-		if ($fieldDef['dbType'] == 'uint')
1019
-			$fieldDef['len'] = '10';
1020
-		if ($fieldDef['dbType'] == 'int' && empty($fieldDef['len']) )
1021
-			$fieldDef['len'] = '11';
1022
-
1023
-		if($fieldDef['dbType'] == 'decimal') {
1024
-			if(isset($fieldDef['len'])) {
1025
-				if(strstr($fieldDef['len'], ",") === false) {
1026
-					$fieldDef['len'] .= ",0";
1027
-				}
1028
-			} else {
1029
-				$fieldDef['len']  = '10,0';
1030
-			}
1031
-		}
1032
-	}
1033
-
1034
-	/**
1035
-	 * Generates SQL for dropping a table.
1036
-	 *
1037
-	 * @param  string $name table name
1038
-	 * @return string SQL statement
1039
-	 */
1040
-	public function dropTableNameSQL($name)
1041
-	{
1042
-		return "DROP TABLE IF EXISTS ".$name;
1043
-	}
1044
-
1045
-	public function dropIndexes($tablename, $indexes, $execute = true)
1046
-	{
1047
-		$sql = array();
1048
-		foreach ($indexes as $index) {
1049
-			$name =$index['name'];
1050
-			if($execute) {
1051
-			unset(self::$index_descriptions[$tablename][$name]);
1052
-			}
1053
-			if ($index['type'] == 'primary') {
1054
-				$sql[] = 'DROP PRIMARY KEY';
1055
-			} else {
1056
-				$sql[] = "DROP INDEX $name";
1057
-			}
1058
-		}
1059
-		if (!empty($sql)) {
762
+                $ref['default'] = '';
763
+
764
+        if ( $return_as_array )
765
+            return $ref;
766
+        else
767
+            return "{$ref['name']} {$ref['colType']} {$ref['default']} {$ref['required']} {$ref['auto_increment']}";
768
+    }
769
+
770
+    /**
771
+     * @see DBManager::changeColumnSQL()
772
+     */
773
+    protected function changeColumnSQL($tablename, $fieldDefs, $action, $ignoreRequired = false)
774
+    {
775
+        $columns = array();
776
+        if ($this->isFieldArray($fieldDefs)){
777
+            foreach ($fieldDefs as $def){
778
+                if ($action == 'drop')
779
+                    $columns[] = $def['name'];
780
+                else
781
+                    $columns[] = $this->oneColumnSQLRep($def, $ignoreRequired);
782
+            }
783
+        } else {
784
+            if ($action == 'drop')
785
+                $columns[] = $fieldDefs['name'];
786
+        else
787
+            $columns[] = $this->oneColumnSQLRep($fieldDefs);
788
+        }
789
+
790
+        return "ALTER TABLE $tablename $action COLUMN ".implode(",$action column ", $columns);
791
+    }
792
+
793
+    /**
794
+     * Generates SQL for key specification inside CREATE TABLE statement
795
+     *
796
+     * The passes array is an array of field definitions or a field definition
797
+     * itself. The keys generated will be either primary, foreign, unique, index
798
+     * or none at all depending on the setting of the "key" parameter of a field definition
799
+     *
800
+     * @param  array  $indices
801
+     * @param  bool   $alter_table
802
+     * @param  string $alter_action
803
+     * @return string SQL Statement
804
+     */
805
+    protected function keysSQL($indices, $alter_table = false, $alter_action = '')
806
+    {
807
+    // check if the passed value is an array of fields.
808
+    // if not, convert it into an array
809
+    if (!$this->isFieldArray($indices))
810
+        $indices[] = $indices;
811
+
812
+    $columns = array();
813
+    foreach ($indices as $index) {
814
+        if(!empty($index['db']) && $index['db'] != $this->dbType)
815
+            continue;
816
+        if (isset($index['source']) && $index['source'] != 'db')
817
+            continue;
818
+
819
+        $type = $index['type'];
820
+        $name = $index['name'];
821
+
822
+        if (is_array($index['fields']))
823
+            $fields = implode(", ", $index['fields']);
824
+        else
825
+            $fields = $index['fields'];
826
+
827
+        switch ($type) {
828
+        case 'unique':
829
+            $columns[] = " UNIQUE $name ($fields)";
830
+            break;
831
+        case 'primary':
832
+            $columns[] = " PRIMARY KEY ($fields)";
833
+            break;
834
+        case 'index':
835
+        case 'foreign':
836
+        case 'clustered':
837
+        case 'alternate_key':
838
+            /**
839
+             * @todo here it is assumed that the primary key of the foreign
840
+             * table will always be named 'id'. It must be noted though
841
+             * that this can easily be fixed by referring to db dictionary
842
+             * to find the correct primary field name
843
+             */
844
+            if ( $alter_table )
845
+                $columns[] = " INDEX $name ($fields)";
846
+            else
847
+                $columns[] = " KEY $name ($fields)";
848
+            break;
849
+        case 'fulltext':
850
+            if ($this->full_text_indexing_installed())
851
+                $columns[] = " FULLTEXT ($fields)";
852
+            else
853
+                $GLOBALS['log']->debug('MYISAM engine is not available/enabled, full-text indexes will be skipped. Skipping:',$name);
854
+            break;
855
+        }
856
+    }
857
+    $columns = implode(", $alter_action ", $columns);
858
+    if(!empty($alter_action)){
859
+        $columns = $alter_action . ' '. $columns;
860
+    }
861
+    return $columns;
862
+    }
863
+
864
+    /**
865
+     * @see DBManager::setAutoIncrement()
866
+     */
867
+    protected function setAutoIncrement($table, $field_name)
868
+    {
869
+        return "auto_increment";
870
+    }
871
+
872
+    /**
873
+     * Sets the next auto-increment value of a column to a specific value.
874
+     *
875
+     * @param  string $table tablename
876
+     * @param  string $field_name
877
+     */
878
+    public function setAutoIncrementStart($table, $field_name, $start_value)
879
+    {
880
+        $start_value = (int)$start_value;
881
+        return $this->query( "ALTER TABLE $table AUTO_INCREMENT = $start_value;");
882
+    }
883
+
884
+    /**
885
+     * Returns the next value for an auto increment
886
+     *
887
+     * @param  string $table tablename
888
+     * @param  string $field_name
889
+     * @return string
890
+     */
891
+    public function getAutoIncrement($table, $field_name)
892
+    {
893
+        $result = $this->query("SHOW TABLE STATUS LIKE '$table'");
894
+        $row = $this->fetchByAssoc($result);
895
+        if (!empty($row['Auto_increment']))
896
+            return $row['Auto_increment'];
897
+
898
+        return "";
899
+    }
900
+
901
+    /**
902
+     * @see DBManager::get_indices()
903
+     */
904
+    public function get_indices($tablename)
905
+    {
906
+        //find all unique indexes and primary keys.
907
+        $result = $this->query("SHOW INDEX FROM $tablename");
908
+
909
+        $indices = array();
910
+        while (($row=$this->fetchByAssoc($result)) !=null) {
911
+            $index_type='index';
912
+            if ($row['Key_name'] =='PRIMARY') {
913
+                $index_type='primary';
914
+            }
915
+            elseif ( $row['Non_unique'] == '0' ) {
916
+                $index_type='unique';
917
+            }
918
+            $name = strtolower($row['Key_name']);
919
+            $indices[$name]['name']=$name;
920
+            $indices[$name]['type']=$index_type;
921
+            $indices[$name]['fields'][]=strtolower($row['Column_name']);
922
+        }
923
+        return $indices;
924
+    }
925
+
926
+    /**
927
+     * @see DBManager::add_drop_constraint()
928
+     */
929
+    public function add_drop_constraint($table, $definition, $drop = false)
930
+    {
931
+        $type         = $definition['type'];
932
+        $fields       = implode(',',$definition['fields']);
933
+        $name         = $definition['name'];
934
+        $sql          = '';
935
+
936
+        switch ($type){
937
+        // generic indices
938
+        case 'index':
939
+        case 'alternate_key':
940
+        case 'clustered':
941
+            if ($drop)
942
+                $sql = "ALTER TABLE {$table} DROP INDEX {$name} ";
943
+            else
944
+                $sql = "ALTER TABLE {$table} ADD INDEX {$name} ({$fields})";
945
+            break;
946
+        // constraints as indices
947
+        case 'unique':
948
+            if ($drop)
949
+                $sql = "ALTER TABLE {$table} DROP INDEX $name";
950
+            else
951
+                $sql = "ALTER TABLE {$table} ADD CONSTRAINT UNIQUE {$name} ({$fields})";
952
+            break;
953
+        case 'primary':
954
+            if ($drop)
955
+                $sql = "ALTER TABLE {$table} DROP PRIMARY KEY";
956
+            else
957
+                $sql = "ALTER TABLE {$table} ADD CONSTRAINT PRIMARY KEY ({$fields})";
958
+            break;
959
+        case 'foreign':
960
+            if ($drop)
961
+                $sql = "ALTER TABLE {$table} DROP FOREIGN KEY ({$fields})";
962
+            else
963
+                $sql = "ALTER TABLE {$table} ADD CONSTRAINT FOREIGN KEY {$name} ({$fields}) REFERENCES {$definition['foreignTable']}({$definition['foreignField']})";
964
+            break;
965
+        }
966
+        return $sql;
967
+    }
968
+
969
+    /**
970
+     * Runs a query and returns a single row
971
+     *
972
+     * @param  string   $sql        SQL Statement to execute
973
+     * @param  bool     $dieOnError True if we want to call die if the query returns errors
974
+     * @param  string   $msg        Message to log if error occurs
975
+     * @param  bool     $suppress   Message to log if error occurs
976
+     * @return array    single row from the query
977
+     */
978
+    public function fetchOne($sql, $dieOnError = false, $msg = '', $suppress = false)
979
+    {
980
+        if(stripos($sql, ' LIMIT ') === false) {
981
+            // little optimization to just fetch one row
982
+            $sql .= " LIMIT 0,1";
983
+        }
984
+        return parent::fetchOne($sql, $dieOnError, $msg, $suppress);
985
+    }
986
+
987
+    /**
988
+     * @see DBManager::full_text_indexing_installed()
989
+     */
990
+    public function full_text_indexing_installed($dbname = null)
991
+    {
992
+        return $this->isEngineEnabled('MyISAM');
993
+    }
994
+
995
+    /**
996
+     * @see DBManager::massageFieldDef()
997
+     */
998
+    public function massageFieldDef(&$fieldDef, $tablename)
999
+    {
1000
+        parent::massageFieldDef($fieldDef,$tablename);
1001
+
1002
+        if ( isset($fieldDef['default']) &&
1003
+            ($fieldDef['dbType'] == 'text'
1004
+                || $fieldDef['dbType'] == 'blob'
1005
+                || $fieldDef['dbType'] == 'longtext'
1006
+                || $fieldDef['dbType'] == 'longblob' ))
1007
+            unset($fieldDef['default']);
1008
+        if ($fieldDef['dbType'] == 'uint')
1009
+            $fieldDef['len'] = '10';
1010
+        if ($fieldDef['dbType'] == 'ulong')
1011
+            $fieldDef['len'] = '20';
1012
+        if ($fieldDef['dbType'] == 'bool')
1013
+            $fieldDef['type'] = 'tinyint';
1014
+        if ($fieldDef['dbType'] == 'bool' && empty($fieldDef['default']) )
1015
+            $fieldDef['default'] = '0';
1016
+        if (($fieldDef['dbType'] == 'varchar' || $fieldDef['dbType'] == 'enum') && empty($fieldDef['len']) )
1017
+            $fieldDef['len'] = '255';
1018
+        if ($fieldDef['dbType'] == 'uint')
1019
+            $fieldDef['len'] = '10';
1020
+        if ($fieldDef['dbType'] == 'int' && empty($fieldDef['len']) )
1021
+            $fieldDef['len'] = '11';
1022
+
1023
+        if($fieldDef['dbType'] == 'decimal') {
1024
+            if(isset($fieldDef['len'])) {
1025
+                if(strstr($fieldDef['len'], ",") === false) {
1026
+                    $fieldDef['len'] .= ",0";
1027
+                }
1028
+            } else {
1029
+                $fieldDef['len']  = '10,0';
1030
+            }
1031
+        }
1032
+    }
1033
+
1034
+    /**
1035
+     * Generates SQL for dropping a table.
1036
+     *
1037
+     * @param  string $name table name
1038
+     * @return string SQL statement
1039
+     */
1040
+    public function dropTableNameSQL($name)
1041
+    {
1042
+        return "DROP TABLE IF EXISTS ".$name;
1043
+    }
1044
+
1045
+    public function dropIndexes($tablename, $indexes, $execute = true)
1046
+    {
1047
+        $sql = array();
1048
+        foreach ($indexes as $index) {
1049
+            $name =$index['name'];
1050
+            if($execute) {
1051
+            unset(self::$index_descriptions[$tablename][$name]);
1052
+            }
1053
+            if ($index['type'] == 'primary') {
1054
+                $sql[] = 'DROP PRIMARY KEY';
1055
+            } else {
1056
+                $sql[] = "DROP INDEX $name";
1057
+            }
1058
+        }
1059
+        if (!empty($sql)) {
1060 1060
             $sql = "ALTER TABLE $tablename " . join(",", $sql) . ";";
1061
-			if($execute)
1062
-				$this->query($sql);
1063
-		} else {
1064
-			$sql = '';
1065
-		}
1066
-		return $sql;
1067
-	}
1068
-
1069
-	/**
1070
-	 * List of available collation settings
1071
-	 * @return string
1072
-	 */
1073
-	public function getDefaultCollation()
1074
-	{
1075
-		return "utf8_general_ci";
1076
-	}
1077
-
1078
-	/**
1079
-	 * List of available collation settings
1080
-	 * @return array
1081
-	 */
1082
-	public function getCollationList()
1083
-	{
1084
-		$q = "SHOW COLLATION LIKE 'utf8%'";
1085
-		$r = $this->query($q);
1086
-		$res = array();
1087
-		while($a = $this->fetchByAssoc($r)) {
1088
-			$res[] = $a['Collation'];
1089
-		}
1090
-		return $res;
1091
-	}
1092
-
1093
-	/**
1094
-	 * (non-PHPdoc)
1095
-	 * @see DBManager::renameColumnSQL()
1096
-	 */
1097
-	public function renameColumnSQL($tablename, $column, $newname)
1098
-	{
1099
-		$field = $this->describeField($column, $tablename);
1100
-		$field['name'] = $newname;
1101
-		return "ALTER TABLE $tablename CHANGE COLUMN $column ".$this->oneColumnSQLRep($field);
1102
-	}
1103
-
1104
-	public function emptyValue($type)
1105
-	{
1106
-		$ctype = $this->getColumnType($type);
1107
-		if($ctype == "datetime") {
1108
-			return $this->convert($this->quoted("0000-00-00 00:00:00"), "datetime");
1109
-		}
1110
-		if($ctype == "date") {
1111
-			return $this->convert($this->quoted("0000-00-00"), "date");
1112
-		}
1113
-		if($ctype == "time") {
1114
-			return $this->convert($this->quoted("00:00:00"), "time");
1115
-		}
1116
-		return parent::emptyValue($type);
1117
-	}
1118
-
1119
-	/**
1120
-	 * (non-PHPdoc)
1121
-	 * @see DBManager::lastDbError()
1122
-	 */
1123
-	public function lastDbError()
1124
-	{
1125
-		if($this->database) {
1126
-		    if(mysql_errno($this->database)) {
1127
-			    return "MySQL error ".mysql_errno($this->database).": ".mysql_error($this->database);
1128
-		    }
1129
-		} else {
1130
-			$err =  mysql_error();
1131
-			if($err) {
1132
-			    return $err;
1133
-			}
1134
-		}
1061
+            if($execute)
1062
+                $this->query($sql);
1063
+        } else {
1064
+            $sql = '';
1065
+        }
1066
+        return $sql;
1067
+    }
1068
+
1069
+    /**
1070
+     * List of available collation settings
1071
+     * @return string
1072
+     */
1073
+    public function getDefaultCollation()
1074
+    {
1075
+        return "utf8_general_ci";
1076
+    }
1077
+
1078
+    /**
1079
+     * List of available collation settings
1080
+     * @return array
1081
+     */
1082
+    public function getCollationList()
1083
+    {
1084
+        $q = "SHOW COLLATION LIKE 'utf8%'";
1085
+        $r = $this->query($q);
1086
+        $res = array();
1087
+        while($a = $this->fetchByAssoc($r)) {
1088
+            $res[] = $a['Collation'];
1089
+        }
1090
+        return $res;
1091
+    }
1092
+
1093
+    /**
1094
+     * (non-PHPdoc)
1095
+     * @see DBManager::renameColumnSQL()
1096
+     */
1097
+    public function renameColumnSQL($tablename, $column, $newname)
1098
+    {
1099
+        $field = $this->describeField($column, $tablename);
1100
+        $field['name'] = $newname;
1101
+        return "ALTER TABLE $tablename CHANGE COLUMN $column ".$this->oneColumnSQLRep($field);
1102
+    }
1103
+
1104
+    public function emptyValue($type)
1105
+    {
1106
+        $ctype = $this->getColumnType($type);
1107
+        if($ctype == "datetime") {
1108
+            return $this->convert($this->quoted("0000-00-00 00:00:00"), "datetime");
1109
+        }
1110
+        if($ctype == "date") {
1111
+            return $this->convert($this->quoted("0000-00-00"), "date");
1112
+        }
1113
+        if($ctype == "time") {
1114
+            return $this->convert($this->quoted("00:00:00"), "time");
1115
+        }
1116
+        return parent::emptyValue($type);
1117
+    }
1118
+
1119
+    /**
1120
+     * (non-PHPdoc)
1121
+     * @see DBManager::lastDbError()
1122
+     */
1123
+    public function lastDbError()
1124
+    {
1125
+        if($this->database) {
1126
+            if(mysql_errno($this->database)) {
1127
+                return "MySQL error ".mysql_errno($this->database).": ".mysql_error($this->database);
1128
+            }
1129
+        } else {
1130
+            $err =  mysql_error();
1131
+            if($err) {
1132
+                return $err;
1133
+            }
1134
+        }
1135 1135
         return false;
1136 1136
     }
1137 1137
 
1138
-	/**
1139
-	 * Quote MySQL search term
1140
-	 * @param unknown_type $term
1141
-	 */
1142
-	protected function quoteTerm($term)
1143
-	{
1144
-		if(strpos($term, ' ') !== false) {
1145
-			return '"'.$term.'"';
1146
-		}
1147
-		return $term;
1148
-	}
1149
-
1150
-	/**
1151
-	 * Generate fulltext query from set of terms
1152
-	 * @param string $fields Field to search against
1153
-	 * @param array $terms Search terms that may be or not be in the result
1154
-	 * @param array $must_terms Search terms that have to be in the result
1155
-	 * @param array $exclude_terms Search terms that have to be not in the result
1156
-	 */
1157
-	public function getFulltextQuery($field, $terms, $must_terms = array(), $exclude_terms = array())
1158
-	{
1159
-		$condition = array();
1160
-		foreach($terms as $term) {
1161
-			$condition[] = $this->quoteTerm($term);
1162
-		}
1163
-		foreach($must_terms as $term) {
1164
-			$condition[] = "+".$this->quoteTerm($term);
1165
-		}
1166
-		foreach($exclude_terms as $term) {
1167
-			$condition[] = "-".$this->quoteTerm($term);
1168
-		}
1169
-		$condition = $this->quoted(join(" ",$condition));
1170
-		return "MATCH($field) AGAINST($condition IN BOOLEAN MODE)";
1171
-	}
1172
-
1173
-	/**
1174
-	 * Get list of all defined charsets
1175
-	 * @return array
1176
-	 */
1177
-	protected function getCharsetInfo()
1178
-	{
1179
-		$charsets = array();
1180
-		$res = $this->query("show variables like 'character\\_set\\_%'");
1181
-		while($row = $this->fetchByAssoc($res)) {
1182
-			$charsets[$row['Variable_name']] = $row['Value'];
1183
-		}
1184
-		return $charsets;
1185
-	}
1186
-
1187
-	public function getDbInfo()
1188
-	{
1189
-		$charsets = $this->getCharsetInfo();
1190
-		$charset_str = array();
1191
-		foreach($charsets as $name => $value) {
1192
-			$charset_str[] = "$name = $value";
1193
-		}
1194
-		return array(
1195
-			"MySQL Version" => @mysql_get_client_info(),
1196
-			"MySQL Host Info" => @mysql_get_host_info($this->database),
1197
-			"MySQL Server Info" => @mysql_get_server_info($this->database),
1198
-			"MySQL Client Encoding" =>  @mysql_client_encoding($this->database),
1199
-			"MySQL Character Set Settings" => join(", ", $charset_str),
1200
-		);
1201
-	}
1202
-
1203
-	public function validateQuery($query)
1204
-	{
1205
-		$res = $this->query("EXPLAIN $query");
1206
-		return !empty($res);
1207
-	}
1208
-
1209
-	protected function makeTempTableCopy($table)
1210
-	{
1211
-		$this->log->debug("creating temp table for [$table]...");
1212
-		$result = $this->query("SHOW CREATE TABLE {$table}");
1213
-		if(empty($result)) {
1214
-			return false;
1215
-		}
1216
-		$row = $this->fetchByAssoc($result);
1217
-		if(empty($row) || empty($row['Create Table'])) {
1218
-		    return false;
1219
-		}
1220
-		$create = $row['Create Table'];
1221
-		// rewrite DDL with _temp name
1222
-		$tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $create);
1223
-		$r2 = $this->query($tempTableQuery);
1224
-		if(empty($r2)) {
1225
-			return false;
1226
-		}
1227
-
1228
-		// get sample data into the temp table to test for data/constraint conflicts
1229
-		$this->log->debug('inserting temp dataset...');
1230
-		$q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1231
-		$this->query($q3, false, "Preflight Failed for: {$q3}");
1232
-		return true;
1233
-	}
1234
-
1235
-	/**
1236
-	 * Tests an ALTER TABLE query
1237
-	 * @param string table The table name to get DDL
1238
-	 * @param string query The query to test.
1239
-	 * @return string Non-empty if error found
1240
-	 */
1241
-	protected function verifyAlterTable($table, $query)
1242
-	{
1243
-		$this->log->debug("verifying ALTER TABLE");
1244
-		// Skipping ALTER TABLE [table] DROP PRIMARY KEY because primary keys are not being copied
1245
-		// over to the temp tables
1246
-		if(strpos(strtoupper($query), 'DROP PRIMARY KEY') !== false) {
1247
-			$this->log->debug("Skipping DROP PRIMARY KEY");
1248
-			return '';
1249
-		}
1250
-		if(!$this->makeTempTableCopy($table)) {
1251
-			return 'Could not create temp table copy';
1252
-		}
1253
-
1254
-		// test the query on the test table
1255
-		$this->log->debug('testing query: ['.$query.']');
1256
-		$tempTableTestQuery = str_replace("ALTER TABLE `{$table}`", "ALTER TABLE `{$table}__uw_temp`", $query);
1257
-		if (strpos($tempTableTestQuery, 'idx') === false) {
1258
-			if(strpos($tempTableTestQuery, '__uw_temp') === false) {
1259
-				return 'Could not use a temp table to test query!';
1260
-			}
1261
-
1262
-			$this->log->debug('testing query on temp table: ['.$tempTableTestQuery.']');
1263
-			$this->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1264
-		} else {
1265
-			// test insertion of an index on a table
1266
-			$tempTableTestQuery_idx = str_replace("ADD INDEX `idx_", "ADD INDEX `temp_idx_", $tempTableTestQuery);
1267
-			$this->log->debug('testing query on temp table: ['.$tempTableTestQuery_idx.']');
1268
-			$this->query($tempTableTestQuery_idx, false, "Preflight Failed for: {$query}");
1269
-		}
1270
-		$mysqlError = $this->getL();
1271
-		if(!empty($mysqlError)) {
1272
-			return $mysqlError;
1273
-		}
1274
-		$this->dropTableName("{$table}__uw_temp");
1275
-
1276
-		return '';
1277
-	}
1278
-
1279
-	protected function verifyGenericReplaceQuery($querytype, $table, $query)
1280
-	{
1281
-		$this->log->debug("verifying $querytype statement");
1282
-
1283
-		if(!$this->makeTempTableCopy($table)) {
1284
-			return 'Could not create temp table copy';
1285
-		}
1286
-		// test the query on the test table
1287
-		$this->log->debug('testing query: ['.$query.']');
1288
-		$tempTableTestQuery = str_replace("$querytype `{$table}`", "$querytype `{$table}__uw_temp`", $query);
1289
-		if(strpos($tempTableTestQuery, '__uw_temp') === false) {
1290
-			return 'Could not use a temp table to test query!';
1291
-		}
1292
-
1293
-		$this->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1294
-		$error = $this->lastError(); // empty on no-errors
1295
-		$this->dropTableName("{$table}__uw_temp"); // just in case
1296
-		return $error;
1297
-	}
1298
-
1299
-	/**
1300
-	 * Tests a DROP TABLE query
1301
-	 * @param string table The table name to get DDL
1302
-	 * @param string query The query to test.
1303
-	 * @return string Non-empty if error found
1304
-	 */
1305
-	public function verifyDropTable($table, $query)
1306
-	{
1307
-		return $this->verifyGenericReplaceQuery("DROP TABLE", $table, $query);
1308
-	}
1309
-
1310
-	/**
1311
-	 * Tests an INSERT INTO query
1312
-	 * @param string table The table name to get DDL
1313
-	 * @param string query The query to test.
1314
-	 * @return string Non-empty if error found
1315
-	 */
1316
-	public function verifyInsertInto($table, $query)
1317
-	{
1318
-		return $this->verifyGenericReplaceQuery("INSERT INTO", $table, $query);
1319
-	}
1320
-
1321
-	/**
1322
-	 * Tests an UPDATE query
1323
-	 * @param string table The table name to get DDL
1324
-	 * @param string query The query to test.
1325
-	 * @return string Non-empty if error found
1326
-	 */
1327
-	public function verifyUpdate($table, $query)
1328
-	{
1329
-		return $this->verifyGenericReplaceQuery("UPDATE", $table, $query);
1330
-	}
1331
-
1332
-	/**
1333
-	 * Tests an DELETE FROM query
1334
-	 * @param string table The table name to get DDL
1335
-	 * @param string query The query to test.
1336
-	 * @return string Non-empty if error found
1337
-	 */
1338
-	public function verifyDeleteFrom($table, $query)
1339
-	{
1340
-		return $this->verifyGenericReplaceQuery("DELETE FROM", $table, $query);
1341
-	}
1342
-
1343
-	/**
1344
-	 * Check if certain database exists
1345
-	 * @param string $dbname
1346
-	 */
1347
-	public function dbExists($dbname)
1348
-	{
1349
-		$db = $this->getOne("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ".$this->quoted($dbname));
1350
-		return !empty($db);
1351
-	}
1352
-
1353
-	/**
1354
-	 * Select database
1355
-	 * @param string $dbname
1356
-	 */
1357
-	protected function selectDb($dbname)
1358
-	{
1359
-		return mysql_select_db($dbname);
1360
-	}
1361
-
1362
-	/**
1363
-	 * Check if certain DB user exists
1364
-	 * @param string $username
1365
-	 */
1366
-	public function userExists($username)
1367
-	{
1368
-		$db = $this->getOne("SELECT DATABASE()");
1369
-		if(!$this->selectDb("mysql")) {
1370
-			return false;
1371
-		}
1372
-		$user = $this->getOne("select count(*) from user where user = ".$this->quoted($username));
1373
-		if(!$this->selectDb($db)) {
1374
-			$this->checkError("Cannot select database $db", true);
1375
-		}
1376
-		return !empty($user);
1377
-	}
1378
-
1379
-	/**
1380
-	 * Create DB user
1381
-	 * @param string $database_name
1382
-	 * @param string $host_name
1383
-	 * @param string $user
1384
-	 * @param string $password
1385
-	 */
1386
-	public function createDbUser($database_name, $host_name, $user, $password)
1387
-	{
1388
-		$qpassword = $this->quote($password);
1389
-		$this->query("GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX
1138
+    /**
1139
+     * Quote MySQL search term
1140
+     * @param unknown_type $term
1141
+     */
1142
+    protected function quoteTerm($term)
1143
+    {
1144
+        if(strpos($term, ' ') !== false) {
1145
+            return '"'.$term.'"';
1146
+        }
1147
+        return $term;
1148
+    }
1149
+
1150
+    /**
1151
+     * Generate fulltext query from set of terms
1152
+     * @param string $fields Field to search against
1153
+     * @param array $terms Search terms that may be or not be in the result
1154
+     * @param array $must_terms Search terms that have to be in the result
1155
+     * @param array $exclude_terms Search terms that have to be not in the result
1156
+     */
1157
+    public function getFulltextQuery($field, $terms, $must_terms = array(), $exclude_terms = array())
1158
+    {
1159
+        $condition = array();
1160
+        foreach($terms as $term) {
1161
+            $condition[] = $this->quoteTerm($term);
1162
+        }
1163
+        foreach($must_terms as $term) {
1164
+            $condition[] = "+".$this->quoteTerm($term);
1165
+        }
1166
+        foreach($exclude_terms as $term) {
1167
+            $condition[] = "-".$this->quoteTerm($term);
1168
+        }
1169
+        $condition = $this->quoted(join(" ",$condition));
1170
+        return "MATCH($field) AGAINST($condition IN BOOLEAN MODE)";
1171
+    }
1172
+
1173
+    /**
1174
+     * Get list of all defined charsets
1175
+     * @return array
1176
+     */
1177
+    protected function getCharsetInfo()
1178
+    {
1179
+        $charsets = array();
1180
+        $res = $this->query("show variables like 'character\\_set\\_%'");
1181
+        while($row = $this->fetchByAssoc($res)) {
1182
+            $charsets[$row['Variable_name']] = $row['Value'];
1183
+        }
1184
+        return $charsets;
1185
+    }
1186
+
1187
+    public function getDbInfo()
1188
+    {
1189
+        $charsets = $this->getCharsetInfo();
1190
+        $charset_str = array();
1191
+        foreach($charsets as $name => $value) {
1192
+            $charset_str[] = "$name = $value";
1193
+        }
1194
+        return array(
1195
+            "MySQL Version" => @mysql_get_client_info(),
1196
+            "MySQL Host Info" => @mysql_get_host_info($this->database),
1197
+            "MySQL Server Info" => @mysql_get_server_info($this->database),
1198
+            "MySQL Client Encoding" =>  @mysql_client_encoding($this->database),
1199
+            "MySQL Character Set Settings" => join(", ", $charset_str),
1200
+        );
1201
+    }
1202
+
1203
+    public function validateQuery($query)
1204
+    {
1205
+        $res = $this->query("EXPLAIN $query");
1206
+        return !empty($res);
1207
+    }
1208
+
1209
+    protected function makeTempTableCopy($table)
1210
+    {
1211
+        $this->log->debug("creating temp table for [$table]...");
1212
+        $result = $this->query("SHOW CREATE TABLE {$table}");
1213
+        if(empty($result)) {
1214
+            return false;
1215
+        }
1216
+        $row = $this->fetchByAssoc($result);
1217
+        if(empty($row) || empty($row['Create Table'])) {
1218
+            return false;
1219
+        }
1220
+        $create = $row['Create Table'];
1221
+        // rewrite DDL with _temp name
1222
+        $tempTableQuery = str_replace("CREATE TABLE `{$table}`", "CREATE TABLE `{$table}__uw_temp`", $create);
1223
+        $r2 = $this->query($tempTableQuery);
1224
+        if(empty($r2)) {
1225
+            return false;
1226
+        }
1227
+
1228
+        // get sample data into the temp table to test for data/constraint conflicts
1229
+        $this->log->debug('inserting temp dataset...');
1230
+        $q3 = "INSERT INTO `{$table}__uw_temp` SELECT * FROM `{$table}` LIMIT 10";
1231
+        $this->query($q3, false, "Preflight Failed for: {$q3}");
1232
+        return true;
1233
+    }
1234
+
1235
+    /**
1236
+     * Tests an ALTER TABLE query
1237
+     * @param string table The table name to get DDL
1238
+     * @param string query The query to test.
1239
+     * @return string Non-empty if error found
1240
+     */
1241
+    protected function verifyAlterTable($table, $query)
1242
+    {
1243
+        $this->log->debug("verifying ALTER TABLE");
1244
+        // Skipping ALTER TABLE [table] DROP PRIMARY KEY because primary keys are not being copied
1245
+        // over to the temp tables
1246
+        if(strpos(strtoupper($query), 'DROP PRIMARY KEY') !== false) {
1247
+            $this->log->debug("Skipping DROP PRIMARY KEY");
1248
+            return '';
1249
+        }
1250
+        if(!$this->makeTempTableCopy($table)) {
1251
+            return 'Could not create temp table copy';
1252
+        }
1253
+
1254
+        // test the query on the test table
1255
+        $this->log->debug('testing query: ['.$query.']');
1256
+        $tempTableTestQuery = str_replace("ALTER TABLE `{$table}`", "ALTER TABLE `{$table}__uw_temp`", $query);
1257
+        if (strpos($tempTableTestQuery, 'idx') === false) {
1258
+            if(strpos($tempTableTestQuery, '__uw_temp') === false) {
1259
+                return 'Could not use a temp table to test query!';
1260
+            }
1261
+
1262
+            $this->log->debug('testing query on temp table: ['.$tempTableTestQuery.']');
1263
+            $this->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1264
+        } else {
1265
+            // test insertion of an index on a table
1266
+            $tempTableTestQuery_idx = str_replace("ADD INDEX `idx_", "ADD INDEX `temp_idx_", $tempTableTestQuery);
1267
+            $this->log->debug('testing query on temp table: ['.$tempTableTestQuery_idx.']');
1268
+            $this->query($tempTableTestQuery_idx, false, "Preflight Failed for: {$query}");
1269
+        }
1270
+        $mysqlError = $this->getL();
1271
+        if(!empty($mysqlError)) {
1272
+            return $mysqlError;
1273
+        }
1274
+        $this->dropTableName("{$table}__uw_temp");
1275
+
1276
+        return '';
1277
+    }
1278
+
1279
+    protected function verifyGenericReplaceQuery($querytype, $table, $query)
1280
+    {
1281
+        $this->log->debug("verifying $querytype statement");
1282
+
1283
+        if(!$this->makeTempTableCopy($table)) {
1284
+            return 'Could not create temp table copy';
1285
+        }
1286
+        // test the query on the test table
1287
+        $this->log->debug('testing query: ['.$query.']');
1288
+        $tempTableTestQuery = str_replace("$querytype `{$table}`", "$querytype `{$table}__uw_temp`", $query);
1289
+        if(strpos($tempTableTestQuery, '__uw_temp') === false) {
1290
+            return 'Could not use a temp table to test query!';
1291
+        }
1292
+
1293
+        $this->query($tempTableTestQuery, false, "Preflight Failed for: {$query}");
1294
+        $error = $this->lastError(); // empty on no-errors
1295
+        $this->dropTableName("{$table}__uw_temp"); // just in case
1296
+        return $error;
1297
+    }
1298
+
1299
+    /**
1300
+     * Tests a DROP TABLE query
1301
+     * @param string table The table name to get DDL
1302
+     * @param string query The query to test.
1303
+     * @return string Non-empty if error found
1304
+     */
1305
+    public function verifyDropTable($table, $query)
1306
+    {
1307
+        return $this->verifyGenericReplaceQuery("DROP TABLE", $table, $query);
1308
+    }
1309
+
1310
+    /**
1311
+     * Tests an INSERT INTO query
1312
+     * @param string table The table name to get DDL
1313
+     * @param string query The query to test.
1314
+     * @return string Non-empty if error found
1315
+     */
1316
+    public function verifyInsertInto($table, $query)
1317
+    {
1318
+        return $this->verifyGenericReplaceQuery("INSERT INTO", $table, $query);
1319
+    }
1320
+
1321
+    /**
1322
+     * Tests an UPDATE query
1323
+     * @param string table The table name to get DDL
1324
+     * @param string query The query to test.
1325
+     * @return string Non-empty if error found
1326
+     */
1327
+    public function verifyUpdate($table, $query)
1328
+    {
1329
+        return $this->verifyGenericReplaceQuery("UPDATE", $table, $query);
1330
+    }
1331
+
1332
+    /**
1333
+     * Tests an DELETE FROM query
1334
+     * @param string table The table name to get DDL
1335
+     * @param string query The query to test.
1336
+     * @return string Non-empty if error found
1337
+     */
1338
+    public function verifyDeleteFrom($table, $query)
1339
+    {
1340
+        return $this->verifyGenericReplaceQuery("DELETE FROM", $table, $query);
1341
+    }
1342
+
1343
+    /**
1344
+     * Check if certain database exists
1345
+     * @param string $dbname
1346
+     */
1347
+    public function dbExists($dbname)
1348
+    {
1349
+        $db = $this->getOne("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ".$this->quoted($dbname));
1350
+        return !empty($db);
1351
+    }
1352
+
1353
+    /**
1354
+     * Select database
1355
+     * @param string $dbname
1356
+     */
1357
+    protected function selectDb($dbname)
1358
+    {
1359
+        return mysql_select_db($dbname);
1360
+    }
1361
+
1362
+    /**
1363
+     * Check if certain DB user exists
1364
+     * @param string $username
1365
+     */
1366
+    public function userExists($username)
1367
+    {
1368
+        $db = $this->getOne("SELECT DATABASE()");
1369
+        if(!$this->selectDb("mysql")) {
1370
+            return false;
1371
+        }
1372
+        $user = $this->getOne("select count(*) from user where user = ".$this->quoted($username));
1373
+        if(!$this->selectDb($db)) {
1374
+            $this->checkError("Cannot select database $db", true);
1375
+        }
1376
+        return !empty($user);
1377
+    }
1378
+
1379
+    /**
1380
+     * Create DB user
1381
+     * @param string $database_name
1382
+     * @param string $host_name
1383
+     * @param string $user
1384
+     * @param string $password
1385
+     */
1386
+    public function createDbUser($database_name, $host_name, $user, $password)
1387
+    {
1388
+        $qpassword = $this->quote($password);
1389
+        $this->query("GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX
1390 1390
 							ON `$database_name`.*
1391 1391
 							TO \"$user\"@\"$host_name\"
1392 1392
 							IDENTIFIED BY '{$qpassword}';", true);
1393 1393
 
1394
-		$this->query("SET PASSWORD FOR \"{$user}\"@\"{$host_name}\" = password('{$qpassword}');", true);
1395
-		if($host_name != 'localhost') {
1396
-			$this->createDbUser($database_name, "localhost", $user, $password);
1397
-		}
1398
-	}
1399
-
1400
-	/**
1401
-	 * Create a database
1402
-	 * @param string $dbname
1403
-	 */
1404
-	public function createDatabase($dbname)
1405
-	{
1406
-		$this->query("CREATE DATABASE `$dbname` CHARACTER SET utf8 COLLATE utf8_general_ci", true);
1407
-	}
1408
-
1409
-	public function preInstall()
1410
-	{
1411
-		$db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
1412
-		$db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
1413
-
1414
-	}
1415
-
1416
-	/**
1417
-	 * Drop a database
1418
-	 * @param string $dbname
1419
-	 */
1420
-	public function dropDatabase($dbname)
1421
-	{
1422
-		return $this->query("DROP DATABASE IF EXISTS `$dbname`", true);
1423
-	}
1424
-
1425
-	/**
1426
-	 * Check if this driver can be used
1427
-	 * @return bool
1428
-	 */
1429
-	public function valid()
1430
-	{
1431
-		return function_exists("mysql_connect");
1432
-	}
1433
-
1434
-	/**
1435
-	 * Check DB version
1436
-	 * @see DBManager::canInstall()
1437
-	 */
1438
-	public function canInstall()
1439
-	{
1440
-		$db_version = $this->version();
1441
-		if(empty($db_version)) {
1442
-			return array('ERR_DB_VERSION_FAILURE');
1443
-		}
1444
-		if(version_compare($db_version, '4.1.2') < 0) {
1445
-			return array('ERR_DB_MYSQL_VERSION', $db_version);
1446
-		}
1447
-		return true;
1448
-	}
1449
-
1450
-	public function installConfig()
1451
-	{
1452
-		return array(
1453
-			'LBL_DBCONFIG_MSG3' =>  array(
1454
-				"setup_db_database_name" => array("label" => 'LBL_DBCONF_DB_NAME', "required" => true),
1455
-			),
1456
-			'LBL_DBCONFIG_MSG2' =>  array(
1457
-				"setup_db_host_name" => array("label" => 'LBL_DBCONF_HOST_NAME', "required" => true),
1458
-			),
1459
-			'LBL_DBCONF_TITLE_USER_INFO' => array(),
1460
-			'LBL_DBCONFIG_B_MSG1' => array(
1461
-				"setup_db_admin_user_name" => array("label" => 'LBL_DBCONF_DB_ADMIN_USER', "required" => true),
1462
-				"setup_db_admin_password" => array("label" => 'LBL_DBCONF_DB_ADMIN_PASSWORD', "type" => "password"),
1463
-			)
1464
-		);
1465
-	}
1466
-
1467
-	/**
1468
-	 * Disable keys on the table
1469
-	 * @abstract
1470
-	 * @param string $tableName
1471
-	 */
1472
-	public function disableKeys($tableName)
1473
-	{
1474
-	    return $this->query('ALTER TABLE '.$tableName.' DISABLE KEYS');
1475
-	}
1476
-
1477
-	/**
1478
-	 * Re-enable keys on the table
1479
-	 * @abstract
1480
-	 * @param string $tableName
1481
-	 */
1482
-	public function enableKeys($tableName)
1483
-	{
1484
-	    return $this->query('ALTER TABLE '.$tableName.' ENABLE KEYS');
1485
-	}
1394
+        $this->query("SET PASSWORD FOR \"{$user}\"@\"{$host_name}\" = password('{$qpassword}');", true);
1395
+        if($host_name != 'localhost') {
1396
+            $this->createDbUser($database_name, "localhost", $user, $password);
1397
+        }
1398
+    }
1399
+
1400
+    /**
1401
+     * Create a database
1402
+     * @param string $dbname
1403
+     */
1404
+    public function createDatabase($dbname)
1405
+    {
1406
+        $this->query("CREATE DATABASE `$dbname` CHARACTER SET utf8 COLLATE utf8_general_ci", true);
1407
+    }
1408
+
1409
+    public function preInstall()
1410
+    {
1411
+        $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
1412
+        $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
1413
+
1414
+    }
1415
+
1416
+    /**
1417
+     * Drop a database
1418
+     * @param string $dbname
1419
+     */
1420
+    public function dropDatabase($dbname)
1421
+    {
1422
+        return $this->query("DROP DATABASE IF EXISTS `$dbname`", true);
1423
+    }
1424
+
1425
+    /**
1426
+     * Check if this driver can be used
1427
+     * @return bool
1428
+     */
1429
+    public function valid()
1430
+    {
1431
+        return function_exists("mysql_connect");
1432
+    }
1433
+
1434
+    /**
1435
+     * Check DB version
1436
+     * @see DBManager::canInstall()
1437
+     */
1438
+    public function canInstall()
1439
+    {
1440
+        $db_version = $this->version();
1441
+        if(empty($db_version)) {
1442
+            return array('ERR_DB_VERSION_FAILURE');
1443
+        }
1444
+        if(version_compare($db_version, '4.1.2') < 0) {
1445
+            return array('ERR_DB_MYSQL_VERSION', $db_version);
1446
+        }
1447
+        return true;
1448
+    }
1449
+
1450
+    public function installConfig()
1451
+    {
1452
+        return array(
1453
+            'LBL_DBCONFIG_MSG3' =>  array(
1454
+                "setup_db_database_name" => array("label" => 'LBL_DBCONF_DB_NAME', "required" => true),
1455
+            ),
1456
+            'LBL_DBCONFIG_MSG2' =>  array(
1457
+                "setup_db_host_name" => array("label" => 'LBL_DBCONF_HOST_NAME', "required" => true),
1458
+            ),
1459
+            'LBL_DBCONF_TITLE_USER_INFO' => array(),
1460
+            'LBL_DBCONFIG_B_MSG1' => array(
1461
+                "setup_db_admin_user_name" => array("label" => 'LBL_DBCONF_DB_ADMIN_USER', "required" => true),
1462
+                "setup_db_admin_password" => array("label" => 'LBL_DBCONF_DB_ADMIN_PASSWORD', "type" => "password"),
1463
+            )
1464
+        );
1465
+    }
1466
+
1467
+    /**
1468
+     * Disable keys on the table
1469
+     * @abstract
1470
+     * @param string $tableName
1471
+     */
1472
+    public function disableKeys($tableName)
1473
+    {
1474
+        return $this->query('ALTER TABLE '.$tableName.' DISABLE KEYS');
1475
+    }
1476
+
1477
+    /**
1478
+     * Re-enable keys on the table
1479
+     * @abstract
1480
+     * @param string $tableName
1481
+     */
1482
+    public function enableKeys($tableName)
1483
+    {
1484
+        return $this->query('ALTER TABLE '.$tableName.' ENABLE KEYS');
1485
+    }
1486 1486
 
1487 1487
     /**
1488 1488
      * Returns a DB specific FROM clause which can be used to select against functions.
@@ -1501,8 +1501,8 @@  discard block
 block discarded – undo
1501 1501
      * @return string
1502 1502
      */
1503 1503
 
1504
-	public function getGuidSQL()
1504
+    public function getGuidSQL()
1505 1505
     {
1506
-      	return 'UUID()';
1506
+            return 'UUID()';
1507 1507
     }
1508 1508
 }
Please login to merge, or discard this patch.
include/database/MysqliManager.php 1 patch
Indentation   +253 added lines, -253 removed lines patch added patch discarded remove patch
@@ -98,51 +98,51 @@  discard block
 block discarded – undo
98 98
  */
99 99
 class MysqliManager extends MysqlManager
100 100
 {
101
-	/**
102
-	 * @see DBManager::$dbType
103
-	 */
104
-	public $dbType = 'mysql';
105
-	public $variant = 'mysqli';
106
-	public $priority = 10;
107
-	public $label = 'LBL_MYSQLI';
108
-
109
-	/**
110
-	 * @see DBManager::$backendFunctions
111
-	 */
112
-	protected $backendFunctions = array(
113
-		'free_result'        => 'mysqli_free_result',
114
-		'close'              => 'mysqli_close',
115
-		'row_count'          => 'mysqli_num_rows',
116
-		'affected_row_count' => 'mysqli_affected_rows',
117
-		);
118
-
119
-	/**
120
-	 * @see MysqlManager::query()
121
-	 */
122
-	public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
123
-	{
124
-		if(is_array($sql)) {
125
-			return $this->queryArray($sql, $dieOnError, $msg, $suppress);
101
+    /**
102
+     * @see DBManager::$dbType
103
+     */
104
+    public $dbType = 'mysql';
105
+    public $variant = 'mysqli';
106
+    public $priority = 10;
107
+    public $label = 'LBL_MYSQLI';
108
+
109
+    /**
110
+     * @see DBManager::$backendFunctions
111
+     */
112
+    protected $backendFunctions = array(
113
+        'free_result'        => 'mysqli_free_result',
114
+        'close'              => 'mysqli_close',
115
+        'row_count'          => 'mysqli_num_rows',
116
+        'affected_row_count' => 'mysqli_affected_rows',
117
+        );
118
+
119
+    /**
120
+     * @see MysqlManager::query()
121
+     */
122
+    public function query($sql, $dieOnError = false, $msg = '', $suppress = false, $keepResult = false)
123
+    {
124
+        if(is_array($sql)) {
125
+            return $this->queryArray($sql, $dieOnError, $msg, $suppress);
126 126
         }
127 127
 
128
-		static $queryMD5 = array();
128
+        static $queryMD5 = array();
129 129
 
130
-		parent::countQuery($sql);
131
-		$GLOBALS['log']->info('Query:' . $sql);
132
-		$this->checkConnection();
133
-		$this->query_time = microtime(true);
134
-		$this->lastsql = $sql;
135
-		$result = $suppress?@mysqli_query($this->database,$sql):mysqli_query($this->database,$sql);
136
-		$md5 = md5($sql);
130
+        parent::countQuery($sql);
131
+        $GLOBALS['log']->info('Query:' . $sql);
132
+        $this->checkConnection();
133
+        $this->query_time = microtime(true);
134
+        $this->lastsql = $sql;
135
+        $result = $suppress?@mysqli_query($this->database,$sql):mysqli_query($this->database,$sql);
136
+        $md5 = md5($sql);
137 137
 
138
-		if (empty($queryMD5[$md5]))
139
-			$queryMD5[$md5] = true;
138
+        if (empty($queryMD5[$md5]))
139
+            $queryMD5[$md5] = true;
140 140
 
141
-		$this->query_time = microtime(true) - $this->query_time;
142
-		$GLOBALS['log']->info('Query Execution Time:'.$this->query_time);
141
+        $this->query_time = microtime(true) - $this->query_time;
142
+        $GLOBALS['log']->info('Query Execution Time:'.$this->query_time);
143 143
 
144
-		// This is some heavy duty debugging, leave commented out unless you need this:
145
-		/*
144
+        // This is some heavy duty debugging, leave commented out unless you need this:
145
+        /*
146 146
 		$bt = debug_backtrace();
147 147
 		for ( $i = count($bt) ; $i-- ; $i > 0 ) {
148 148
 			if ( strpos('MysqliManager.php',$bt[$i]['file']) === false ) {
@@ -154,228 +154,228 @@  discard block
 block discarded – undo
154 154
 		*/
155 155
 
156 156
 
157
-		if($keepResult)
158
-			$this->lastResult = $result;
159
-		$this->checkError($msg.' Query Failed: ' . $sql, $dieOnError);
160
-
161
-		return $result;
162
-	}
163
-
164
-	/**
165
-	 * Returns the number of rows affected by the last query
166
-	 *
167
-	 * @return int
168
-	 */
169
-	public function getAffectedRowCount($result)
170
-	{
171
-		return mysqli_affected_rows($this->getDatabase());
172
-	}
173
-
174
-	/**
175
-	 * Returns the number of rows returned by the result
176
-	 *
177
-	 * This function can't be reliably implemented on most DB, do not use it.
178
-	 * @abstract
179
-	 * @deprecated
180
-	 * @param  resource $result
181
-	 * @return int
182
-	 */
183
-	public function getRowCount($result)
184
-	{
185
-	    return mysqli_num_rows($result);
186
-	}
157
+        if($keepResult)
158
+            $this->lastResult = $result;
159
+        $this->checkError($msg.' Query Failed: ' . $sql, $dieOnError);
187 160
 
161
+        return $result;
162
+    }
188 163
 
189 164
     /**
190
-	 * Disconnects from the database
191
-	 *
192
-	 * Also handles any cleanup needed
193
-	 */
194
-	public function disconnect()
195
-	{
196
-		if(isset($GLOBALS['log']) && !is_null($GLOBALS['log'])) {
197
-			$GLOBALS['log']->debug('Calling MySQLi::disconnect()');
198
-		}
199
-		if(!empty($this->database)){
200
-			$this->freeResult();
201
-			mysqli_close($this->database);
202
-			$this->database = null;
203
-		}
204
-	}
205
-
206
-	/**
207
-	 * @see DBManager::freeDbResult()
208
-	 */
209
-	protected function freeDbResult($dbResult)
210
-	{
211
-		if(!empty($dbResult))
212
-			mysqli_free_result($dbResult);
213
-	}
214
-
215
-	/**
216
-	 * @see DBManager::getFieldsArray()
217
-	 */
218
-	public function getFieldsArray($result, $make_lower_case = false)
219
-	{
220
-		$field_array = array();
221
-
222
-		if (!isset($result) || empty($result))
223
-			return 0;
224
-
225
-		$i = 0;
226
-		while ($i < mysqli_num_fields($result)) {
227
-			$meta = mysqli_fetch_field_direct($result, $i);
228
-			if (!$meta)
229
-				return 0;
230
-
231
-			if($make_lower_case == true)
232
-				$meta->name = strtolower($meta->name);
233
-
234
-			$field_array[] = $meta->name;
235
-
236
-			$i++;
237
-		}
165
+     * Returns the number of rows affected by the last query
166
+     *
167
+     * @return int
168
+     */
169
+    public function getAffectedRowCount($result)
170
+    {
171
+        return mysqli_affected_rows($this->getDatabase());
172
+    }
173
+
174
+    /**
175
+     * Returns the number of rows returned by the result
176
+     *
177
+     * This function can't be reliably implemented on most DB, do not use it.
178
+     * @abstract
179
+     * @deprecated
180
+     * @param  resource $result
181
+     * @return int
182
+     */
183
+    public function getRowCount($result)
184
+    {
185
+        return mysqli_num_rows($result);
186
+    }
187
+
188
+
189
+    /**
190
+     * Disconnects from the database
191
+     *
192
+     * Also handles any cleanup needed
193
+     */
194
+    public function disconnect()
195
+    {
196
+        if(isset($GLOBALS['log']) && !is_null($GLOBALS['log'])) {
197
+            $GLOBALS['log']->debug('Calling MySQLi::disconnect()');
198
+        }
199
+        if(!empty($this->database)){
200
+            $this->freeResult();
201
+            mysqli_close($this->database);
202
+            $this->database = null;
203
+        }
204
+    }
205
+
206
+    /**
207
+     * @see DBManager::freeDbResult()
208
+     */
209
+    protected function freeDbResult($dbResult)
210
+    {
211
+        if(!empty($dbResult))
212
+            mysqli_free_result($dbResult);
213
+    }
214
+
215
+    /**
216
+     * @see DBManager::getFieldsArray()
217
+     */
218
+    public function getFieldsArray($result, $make_lower_case = false)
219
+    {
220
+        $field_array = array();
221
+
222
+        if (!isset($result) || empty($result))
223
+            return 0;
224
+
225
+        $i = 0;
226
+        while ($i < mysqli_num_fields($result)) {
227
+            $meta = mysqli_fetch_field_direct($result, $i);
228
+            if (!$meta)
229
+                return 0;
230
+
231
+            if($make_lower_case == true)
232
+                $meta->name = strtolower($meta->name);
233
+
234
+            $field_array[] = $meta->name;
235
+
236
+            $i++;
237
+        }
238
+
239
+        return $field_array;
240
+    }
241
+
242
+    /**
243
+     * @see DBManager::fetchRow()
244
+     */
245
+    public function fetchRow($result)
246
+    {
247
+        if (empty($result))	return false;
238 248
 
239
-		return $field_array;
240
-	}
241
-
242
-	/**
243
-	 * @see DBManager::fetchRow()
244
-	 */
245
-	public function fetchRow($result)
246
-	{
247
-		if (empty($result))	return false;
248
-
249
-		$row = mysqli_fetch_assoc($result);
250
-		if($row == null) $row = false; //Make sure MySQLi driver results are consistent with other database drivers
251
-		return $row;
252
-	}
253
-
254
-	/**
255
-	 * @see DBManager::quote()
256
-	 */
257
-	public function quote($string)
258
-	{
259
-		return mysqli_real_escape_string($this->getDatabase(),$this->quoteInternal($string));
260
-	}
261
-
262
-	/**
263
-	 * @see DBManager::connect()
264
-	 */
265
-	public function connect(array $configOptions = null, $dieOnError = false)
266
-	{
267
-		global $sugar_config;
268
-
269
-		if (is_null($configOptions))
270
-			$configOptions = $sugar_config['dbconfig'];
271
-
272
-		if(!isset($this->database)) {
273
-
274
-			//mysqli connector has a separate parameter for port.. We need to separate it out from the host name
275
-			$dbhost=$configOptions['db_host_name'];
249
+        $row = mysqli_fetch_assoc($result);
250
+        if($row == null) $row = false; //Make sure MySQLi driver results are consistent with other database drivers
251
+        return $row;
252
+    }
253
+
254
+    /**
255
+     * @see DBManager::quote()
256
+     */
257
+    public function quote($string)
258
+    {
259
+        return mysqli_real_escape_string($this->getDatabase(),$this->quoteInternal($string));
260
+    }
261
+
262
+    /**
263
+     * @see DBManager::connect()
264
+     */
265
+    public function connect(array $configOptions = null, $dieOnError = false)
266
+    {
267
+        global $sugar_config;
268
+
269
+        if (is_null($configOptions))
270
+            $configOptions = $sugar_config['dbconfig'];
271
+
272
+        if(!isset($this->database)) {
273
+
274
+            //mysqli connector has a separate parameter for port.. We need to separate it out from the host name
275
+            $dbhost=$configOptions['db_host_name'];
276 276
             $dbport=isset($configOptions['db_port']) ? ($configOptions['db_port'] == '' ? null : $configOptions['db_port']) : null;
277 277
 			
278
-			$pos=strpos($configOptions['db_host_name'],':');
279
-			if ($pos !== false) {
280
-				$dbhost=substr($configOptions['db_host_name'],0,$pos);
281
-				$dbport=substr($configOptions['db_host_name'],$pos+1);
282
-			}
278
+            $pos=strpos($configOptions['db_host_name'],':');
279
+            if ($pos !== false) {
280
+                $dbhost=substr($configOptions['db_host_name'],0,$pos);
281
+                $dbport=substr($configOptions['db_host_name'],$pos+1);
282
+            }
283
+
284
+            $this->database = @mysqli_connect($dbhost,$configOptions['db_user_name'],$configOptions['db_password'],isset($configOptions['db_name'])?$configOptions['db_name']:'',$dbport);
285
+            if(empty($this->database)) {
286
+                $GLOBALS['log']->fatal("Could not connect to DB server ".$dbhost." as ".$configOptions['db_user_name'].". port " .$dbport . ": " . mysqli_connect_error());
287
+                if($dieOnError) {
288
+                    if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
289
+                        sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
290
+                    } else {
291
+                        sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
292
+                    }
293
+                } else {
294
+                    return false;
295
+                }
296
+            }
297
+        }
283 298
 
284
-			$this->database = @mysqli_connect($dbhost,$configOptions['db_user_name'],$configOptions['db_password'],isset($configOptions['db_name'])?$configOptions['db_name']:'',$dbport);
285
-			if(empty($this->database)) {
286
-				$GLOBALS['log']->fatal("Could not connect to DB server ".$dbhost." as ".$configOptions['db_user_name'].". port " .$dbport . ": " . mysqli_connect_error());
287
-				if($dieOnError) {
288
-					if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
289
-						sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
290
-					} else {
291
-						sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
292
-					}
293
-				} else {
294
-					return false;
295
-				}
296
-			}
297
-		}
299
+        if(!empty($configOptions['db_name']) && !@mysqli_select_db($this->database,$configOptions['db_name'])) {
300
+            $GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}: " . mysqli_connect_error());
301
+            if($dieOnError) {
302
+                    if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
303
+                        sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
304
+                    } else {
305
+                        sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
306
+                    }
307
+            } else {
308
+                return false;
309
+            }
310
+        }
298 311
 
299
-		if(!empty($configOptions['db_name']) && !@mysqli_select_db($this->database,$configOptions['db_name'])) {
300
-			$GLOBALS['log']->fatal( "Unable to select database {$configOptions['db_name']}: " . mysqli_connect_error());
301
-			if($dieOnError) {
302
-					if(isset($GLOBALS['app_strings']['ERR_NO_DB'])) {
303
-						sugar_die($GLOBALS['app_strings']['ERR_NO_DB']);
304
-					} else {
305
-						sugar_die("Could not connect to the database. Please refer to suitecrm.log for details.");
306
-					}
307
-			} else {
308
-				return false;
309
-			}
310
-	    }
311
-
312
-		// cn: using direct calls to prevent this from spamming the Logs
313
-	    mysqli_query($this->database,"SET CHARACTER SET utf8");
314
-	    $names = "SET NAMES 'utf8'";
315
-	    $collation = $this->getOption('collation');
316
-	    if(!empty($collation)) {
317
-	        $names .= " COLLATE '$collation'";
318
-		}
319
-	    mysqli_query($this->database,$names);
320
-
321
-		if($this->checkError('Could Not Connect', $dieOnError))
322
-			$GLOBALS['log']->info("connected to db");
323
-
324
-		$this->connectOptions = $configOptions;
325
-		return true;
326
-	}
327
-
328
-	/**
329
-	 * (non-PHPdoc)
330
-	 * @see MysqlManager::lastDbError()
331
-	 */
332
-	public function lastDbError()
333
-	{
334
-		if($this->database) {
335
-		    if(mysqli_errno($this->database)) {
336
-			    return "MySQL error ".mysqli_errno($this->database).": ".mysqli_error($this->database);
337
-		    }
338
-		} else {
339
-			$err =  mysqli_connect_error();
340
-			if($err) {
341
-			    return $err;
342
-			}
343
-		}
312
+        // cn: using direct calls to prevent this from spamming the Logs
313
+        mysqli_query($this->database,"SET CHARACTER SET utf8");
314
+        $names = "SET NAMES 'utf8'";
315
+        $collation = $this->getOption('collation');
316
+        if(!empty($collation)) {
317
+            $names .= " COLLATE '$collation'";
318
+        }
319
+        mysqli_query($this->database,$names);
344 320
 
345
-		return false;
346
-	}
321
+        if($this->checkError('Could Not Connect', $dieOnError))
322
+            $GLOBALS['log']->info("connected to db");
347 323
 
348
-	public function getDbInfo()
349
-	{
350
-		$charsets = $this->getCharsetInfo();
351
-		$charset_str = array();
352
-		foreach($charsets as $name => $value) {
353
-			$charset_str[] = "$name = $value";
354
-		}
355
-		return array(
356
-			"MySQLi Version" => @mysqli_get_client_info(),
357
-			"MySQLi Host Info" => @mysqli_get_host_info($this->database),
358
-			"MySQLi Server Info" => @mysqli_get_server_info($this->database),
359
-			"MySQLi Client Encoding" =>  @mysqli_client_encoding($this->database),
360
-			"MySQL Character Set Settings" => join(", ", $charset_str),
361
-		);
362
-	}
363
-
364
-	/**
365
-	 * Select database
366
-	 * @param string $dbname
367
-	 */
368
-	protected function selectDb($dbname)
369
-	{
370
-		return mysqli_select_db($this->getDatabase(), $dbname);
371
-	}
372
-
373
-	/**
374
-	 * Check if this driver can be used
375
-	 * @return bool
376
-	 */
377
-	public function valid()
378
-	{
379
-		return function_exists("mysqli_connect") && empty($GLOBALS['sugar_config']['mysqli_disabled']);
380
-	}
324
+        $this->connectOptions = $configOptions;
325
+        return true;
326
+    }
327
+
328
+    /**
329
+     * (non-PHPdoc)
330
+     * @see MysqlManager::lastDbError()
331
+     */
332
+    public function lastDbError()
333
+    {
334
+        if($this->database) {
335
+            if(mysqli_errno($this->database)) {
336
+                return "MySQL error ".mysqli_errno($this->database).": ".mysqli_error($this->database);
337
+            }
338
+        } else {
339
+            $err =  mysqli_connect_error();
340
+            if($err) {
341
+                return $err;
342
+            }
343
+        }
344
+
345
+        return false;
346
+    }
347
+
348
+    public function getDbInfo()
349
+    {
350
+        $charsets = $this->getCharsetInfo();
351
+        $charset_str = array();
352
+        foreach($charsets as $name => $value) {
353
+            $charset_str[] = "$name = $value";
354
+        }
355
+        return array(
356
+            "MySQLi Version" => @mysqli_get_client_info(),
357
+            "MySQLi Host Info" => @mysqli_get_host_info($this->database),
358
+            "MySQLi Server Info" => @mysqli_get_server_info($this->database),
359
+            "MySQLi Client Encoding" =>  @mysqli_client_encoding($this->database),
360
+            "MySQL Character Set Settings" => join(", ", $charset_str),
361
+        );
362
+    }
363
+
364
+    /**
365
+     * Select database
366
+     * @param string $dbname
367
+     */
368
+    protected function selectDb($dbname)
369
+    {
370
+        return mysqli_select_db($this->getDatabase(), $dbname);
371
+    }
372
+
373
+    /**
374
+     * Check if this driver can be used
375
+     * @return bool
376
+     */
377
+    public function valid()
378
+    {
379
+        return function_exists("mysqli_connect") && empty($GLOBALS['sugar_config']['mysqli_disabled']);
380
+    }
381 381
 }
Please login to merge, or discard this patch.
include/database/DBManagerFactory.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
                     }
81 81
                     break;
82 82
                 case "mssql":
83
-                  	if ( function_exists('sqlsrv_connect')
83
+                      if ( function_exists('sqlsrv_connect')
84 84
                                 && (empty($config['db_mssql_force_driver']) || $config['db_mssql_force_driver'] == 'sqlsrv' )) {
85 85
                         $my_db_manager = 'SqlsrvManager';
86 86
                     } elseif (self::isFreeTDS()
@@ -122,20 +122,20 @@  discard block
 block discarded – undo
122 122
     }
123 123
 
124 124
     /**
125
-	 * Returns a reference to the DB object for instance $instanceName, or the default
125
+     * Returns a reference to the DB object for instance $instanceName, or the default
126 126
      * instance if one is not specified
127 127
      *
128 128
      * @param  string $instanceName optional, name of the instance
129 129
      * @return object DBManager instance
130 130
      */
131
-	public static function getInstance($instanceName = '')
131
+    public static function getInstance($instanceName = '')
132 132
     {
133 133
         global $sugar_config;
134 134
         static $count = 0, $old_count = 0;
135 135
 
136 136
         //fall back to the default instance name
137 137
         if(empty($sugar_config['db'][$instanceName])){
138
-        	$instanceName = '';
138
+            $instanceName = '';
139 139
         }
140 140
         if(!isset(self::$instances[$instanceName])){
141 141
             $config = $sugar_config['dbconfig'];
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
     /**
249 249
      * Check if we have freeTDS driver installed
250 250
      * Invoked when connected to mssql. checks if we have freetds version of mssql library.
251
-	 * the response is put into a global variable.
251
+     * the response is put into a global variable.
252 252
      * @return bool
253 253
      */
254 254
     public static function isFreeTDS()
@@ -256,14 +256,14 @@  discard block
 block discarded – undo
256 256
         static $is_freetds = null;
257 257
 
258 258
         if($is_freetds === null) {
259
-    		ob_start();
260
-    		phpinfo(INFO_MODULES);
261
-    		$info=ob_get_contents();
262
-    		ob_end_clean();
259
+            ob_start();
260
+            phpinfo(INFO_MODULES);
261
+            $info=ob_get_contents();
262
+            ob_end_clean();
263 263
 
264
-    		$is_freetds = (strpos($info,'FreeTDS') !== false);
264
+            $is_freetds = (strpos($info,'FreeTDS') !== false);
265 265
         }
266 266
 
267 267
         return $is_freetds;
268
-     }
268
+        }
269 269
 }
270 270
\ No newline at end of file
Please login to merge, or discard this patch.
include/ListView/ListView.php 1 patch
Indentation   +194 added lines, -196 removed lines patch added patch discarded remove patch
@@ -236,8 +236,8 @@  discard block
 block discarded – undo
236 236
  * @param unknown $html_varName
237 237
  * @desc INTERNAL FUNCTION handles the rows
238 238
  */
239
- function process_dynamic_listview_rows($data,$parent_data, $xtemplateSection, $html_varName, $subpanel_def)
240
- {
239
+    function process_dynamic_listview_rows($data,$parent_data, $xtemplateSection, $html_varName, $subpanel_def)
240
+    {
241 241
     global $subpanel_item_count;
242 242
     global $odd_bg;
243 243
     global $even_bg;
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
             $BG_COLOR =  $even_bg;
347 347
         }
348 348
         $oddRow = !$oddRow;
349
-		$button_contents = array();
349
+        $button_contents = array();
350 350
         $this->xTemplate->assign("ROW_COLOR", $ROW_COLOR);
351 351
         $this->xTemplate->assign("BG_COLOR", $BG_COLOR);
352 352
         $layout_manager = $this->getLayoutManager();
@@ -366,43 +366,43 @@  discard block
 block discarded – undo
366 366
             $thepanel=$subpanel_def;
367 367
         }
368 368
 
369
-		/* BEGIN - SECURITY GROUPS */ 
369
+        /* BEGIN - SECURITY GROUPS */ 
370 370
 
371
-		//This check is costly doing it field by field in the below foreach
372
-		//instead pull up here and do once per record....
373
-		$aclaccess_is_owner = false;
374
-		$aclaccess_in_group = false;
371
+        //This check is costly doing it field by field in the below foreach
372
+        //instead pull up here and do once per record....
373
+        $aclaccess_is_owner = false;
374
+        $aclaccess_in_group = false;
375 375
 
376
-		global $current_user;
377
-		if(is_admin($current_user)) {
378
-			$aclaccess_is_owner = true;
379
-		} else {
380
-			$aclaccess_is_owner = $aItem->isOwner($current_user->id);
381
-		}
376
+        global $current_user;
377
+        if(is_admin($current_user)) {
378
+            $aclaccess_is_owner = true;
379
+        } else {
380
+            $aclaccess_is_owner = $aItem->isOwner($current_user->id);
381
+        }
382 382
 
383
-		require_once("modules/SecurityGroups/SecurityGroup.php");
384
-		$aclaccess_in_group = SecurityGroup::groupHasAccess($aItem->module_dir,$aItem->id);
383
+        require_once("modules/SecurityGroups/SecurityGroup.php");
384
+        $aclaccess_in_group = SecurityGroup::groupHasAccess($aItem->module_dir,$aItem->id);
385 385
         	
386
-    	/* END - SECURITY GROUPS */ 
386
+        /* END - SECURITY GROUPS */ 
387 387
     	
388 388
         //get data source name
389 389
         $linked_field=$thepanel->get_data_source_name();
390 390
         $linked_field_set=$thepanel->get_data_source_name(true);
391 391
         static $count;
392 392
         if(!isset($count))$count = 0;
393
-		/* BEGIN - SECURITY GROUPS */ 
394
-		/**
393
+        /* BEGIN - SECURITY GROUPS */ 
394
+        /**
395 395
         $field_acl['DetailView'] = $aItem->ACLAccess('DetailView');
396 396
         $field_acl['ListView'] = $aItem->ACLAccess('ListView');
397 397
         $field_acl['EditView'] = $aItem->ACLAccess('EditView');
398 398
         $field_acl['Delete'] = $aItem->ACLAccess('Delete');
399
-		*/
400
-		//pass is_owner, in_group...vars defined above
399
+         */
400
+        //pass is_owner, in_group...vars defined above
401 401
         $field_acl['DetailView'] = $aItem->ACLAccess('DetailView',$aclaccess_is_owner,$aclaccess_in_group);
402 402
         $field_acl['ListView'] = $aItem->ACLAccess('ListView',$aclaccess_is_owner,$aclaccess_in_group);
403 403
         $field_acl['EditView'] = $aItem->ACLAccess('EditView',$aclaccess_is_owner,$aclaccess_in_group);
404 404
         $field_acl['Delete'] = $aItem->ACLAccess('Delete',$aclaccess_is_owner,$aclaccess_in_group);
405
-		/* END - SECURITY GROUPS */ 
405
+        /* END - SECURITY GROUPS */ 
406 406
         foreach($thepanel->get_list_fields() as $field_name=>$list_field)
407 407
         {
408 408
             //add linked field attribute to the array.
@@ -469,7 +469,7 @@  discard block
 block discarded – undo
469 469
                         // So we'll populate the field data with the pre-rendered display for the field
470 470
                         $list_field['fields'][$field_name] = $widget_contents;
471 471
                         if('full_name' == $field_name){//bug #32465
472
-                           $list_field['fields'][strtoupper($field_name)] = $widget_contents;
472
+                            $list_field['fields'][strtoupper($field_name)] = $widget_contents;
473 473
                         }
474 474
 
475 475
                         //vardef source is non db, assign the field name to varname for processing of column.
@@ -482,7 +482,7 @@  discard block
 block discarded – undo
482 482
                         $widget_contents = $layout_manager->widgetDisplay($list_field);
483 483
                     }
484 484
 
485
-                 $count++;
485
+                    $count++;
486 486
                 $this->xTemplate->assign('CELL_COUNT', $count);
487 487
                 $this->xTemplate->assign('CLASS', "");
488 488
                 if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
@@ -490,15 +490,15 @@  discard block
 block discarded – undo
490 490
                 $this->xTemplate->parse($xtemplateSection.".row.cell");
491 491
                 } else {
492 492
                     // This handles the edit and remove buttons and icon widget
493
-                	if( isset($list_field['widget_class']) && $list_field['widget_class'] == "SubPanelIcon") {
494
-		                $count++;
495
-		                $widget_contents = $layout_manager->widgetDisplay($list_field);
496
-		                $this->xTemplate->assign('CELL_COUNT', $count);
497
-		                $this->xTemplate->assign('CLASS', "");
498
-		                if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
499
-		                $this->xTemplate->assign('CELL', $widget_contents);
500
-		                $this->xTemplate->parse($xtemplateSection.".row.cell");
501
-                	} elseif (preg_match("/button/i", $list_field['name'])) {
493
+                    if( isset($list_field['widget_class']) && $list_field['widget_class'] == "SubPanelIcon") {
494
+                        $count++;
495
+                        $widget_contents = $layout_manager->widgetDisplay($list_field);
496
+                        $this->xTemplate->assign('CELL_COUNT', $count);
497
+                        $this->xTemplate->assign('CLASS', "");
498
+                        if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
499
+                        $this->xTemplate->assign('CELL', $widget_contents);
500
+                        $this->xTemplate->parse($xtemplateSection.".row.cell");
501
+                    } elseif (preg_match("/button/i", $list_field['name'])) {
502 502
                         if ((($list_field['name'] === 'edit_button' && $field_acl['EditView']) || ($list_field['name'] === 'close_button' && $field_acl['EditView']) || ($list_field['name'] === 'remove_button' && $field_acl['Delete'])) && '' != ($_content = $layout_manager->widgetDisplay($list_field)) )
503 503
                         {
504 504
                             $button_contents[] = $_content;
@@ -508,15 +508,15 @@  discard block
 block discarded – undo
508 508
                         {
509 509
                             $button_contents[] = '';
510 510
                         }
511
-                	} else {
512
-               			$count++;
513
-               			$this->xTemplate->assign('CLASS', "");
514
-               			$widget_contents = $layout_manager->widgetDisplay($list_field);
515
-		                $this->xTemplate->assign('CELL_COUNT', $count);
516
-		                if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
517
-		                $this->xTemplate->assign('CELL', $widget_contents);
518
-		                $this->xTemplate->parse($xtemplateSection.".row.cell");
519
-                	}
511
+                    } else {
512
+                            $count++;
513
+                            $this->xTemplate->assign('CLASS', "");
514
+                            $widget_contents = $layout_manager->widgetDisplay($list_field);
515
+                        $this->xTemplate->assign('CELL_COUNT', $count);
516
+                        if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
517
+                        $this->xTemplate->assign('CELL', $widget_contents);
518
+                        $this->xTemplate->parse($xtemplateSection.".row.cell");
519
+                    }
520 520
                 }
521 521
 
522 522
             }
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
  * All Rights Reserved.
580 580
  * Contributor(s): ______________________________________.
581 581
 */
582
- function ListView() {
582
+    function ListView() {
583 583
 
584 584
 
585 585
     if(!$this->initialized) {
@@ -598,11 +598,11 @@  discard block
 block discarded – undo
598 598
  * All Rights Reserved.
599 599
  * Contributor(s): ______________________________________.
600 600
 */
601
- function setRecordsPerPage($count) {
601
+    function setRecordsPerPage($count) {
602 602
     $this->records_per_page = $count;
603 603
 }
604 604
 /**sets the header title */
605
- function setHeaderTitle($value) {
605
+    function setHeaderTitle($value) {
606 606
     $this->header_title = $value;
607 607
 }
608 608
 /**sets the header text this is text that's appended to the header table and is usually used for the creation of buttons
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
  * All Rights Reserved.
611 611
  * Contributor(s): ______________________________________.
612 612
 */
613
- function setHeaderText($value) {
613
+    function setHeaderText($value) {
614 614
     $this->header_text = $value;
615 615
 }
616 616
 /**sets the path for the XTemplate HTML file to be used this is only needed to be set if you are allowing ListView to create the XTemplate
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
  * All Rights Reserved.
619 619
  * Contributor(s): ______________________________________.
620 620
 */
621
- function setXTemplatePath($value) {
621
+    function setXTemplatePath($value) {
622 622
     $this->xTemplatePath= $value;
623 623
 }
624 624
 
@@ -627,7 +627,7 @@  discard block
 block discarded – undo
627 627
  * All Rights Reserved.
628 628
  * Contributor(s): ______________________________________.
629 629
 */
630
- function initNewXTemplate($XTemplatePath, $modString, $imagePath = null) {
630
+    function initNewXTemplate($XTemplatePath, $modString, $imagePath = null) {
631 631
     $this->setXTemplatePath($XTemplatePath);
632 632
     if(isset($modString))
633 633
         $this->setModStrings($modString);
@@ -728,7 +728,7 @@  discard block
 block discarded – undo
728 728
  * All Rights Reserved.
729 729
  * Contributor(s): ______________________________________.
730 730
 */
731
- function setQuery($where, $limit, $orderBy, $varName, $allowOrderByOveride=true) {
731
+    function setQuery($where, $limit, $orderBy, $varName, $allowOrderByOveride=true) {
732 732
     $this->query_where = $where;
733 733
     if($this->getSessionVariable("query", "where") != $where) {
734 734
         $this->query_where_has_changed = true;
@@ -757,7 +757,7 @@  discard block
 block discarded – undo
757 757
  * All Rights Reserved.
758 758
  * Contributor(s): ______________________________________.
759 759
 */
760
- function setTheme($theme) {
760
+    function setTheme($theme) {
761 761
     $this->local_theme = $theme;
762 762
     if(isset($this->xTemplate))$this->xTemplate->assign("THEME", $this->local_theme);
763 763
 }
@@ -767,7 +767,7 @@  discard block
 block discarded – undo
767 767
  * All Rights Reserved.
768 768
  * Contributor(s): ______________________________________.
769 769
 */
770
- function setAppStrings($app_strings) {
770
+    function setAppStrings($app_strings) {
771 771
     unset($this->local_app_strings);
772 772
     $this->local_app_strings = $app_strings;
773 773
     if(isset($this->xTemplate))$this->xTemplate->assign("APP", $this->local_app_strings);
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
  * All Rights Reserved.
779 779
  * Contributor(s): ______________________________________.
780 780
 */
781
- function setModStrings($mod_strings) {
781
+    function setModStrings($mod_strings) {
782 782
     unset($this->local_module_strings);
783 783
     $this->local_mod_strings = $mod_strings;
784 784
     if(isset($this->xTemplate))$this->xTemplate->assign("MOD", $this->local_mod_strings);
@@ -789,7 +789,7 @@  discard block
 block discarded – undo
789 789
  * All Rights Reserved.
790 790
  * Contributor(s): ______________________________________.
791 791
 */
792
- function setImagePath($image_path) {
792
+    function setImagePath($image_path) {
793 793
     $this->local_image_path = $image_path;
794 794
     if(empty($this->local_image_path)) {
795 795
         $this->local_image_path = SugarThemeRegistry::get($this->local_theme)->getImagePath();
@@ -802,7 +802,7 @@  discard block
 block discarded – undo
802 802
  * All Rights Reserved.
803 803
  * Contributor(s): ______________________________________.
804 804
 */
805
- function setCurrentModule($currentModule) {
805
+    function setCurrentModule($currentModule) {
806 806
     unset($this->local_current_module);
807 807
     $this->local_current_module = $currentModule;
808 808
     if(isset($this->xTemplate))$this->xTemplate->assign("MODULE_NAME", $this->local_current_module);
@@ -813,7 +813,7 @@  discard block
 block discarded – undo
813 813
  * All Rights Reserved.
814 814
  * Contributor(s): ______________________________________.
815 815
 */
816
- function createXTemplate() {
816
+    function createXTemplate() {
817 817
     if(!isset($this->xTemplate)) {
818 818
         if(isset($this->xTemplatePath)) {
819 819
 
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
  * All Rights Reserved.
835 835
  * Contributor(s): ______________________________________.
836 836
 */
837
- function setXTemplate($newXTemplate) {
837
+    function setXTemplate($newXTemplate) {
838 838
     $this->xTemplate = $newXTemplate;
839 839
 }
840 840
 
@@ -843,7 +843,7 @@  discard block
 block discarded – undo
843 843
  * All Rights Reserved.
844 844
  * Contributor(s): ______________________________________.
845 845
 */
846
- function getXTemplate() {
846
+    function getXTemplate() {
847 847
     return $this->xTemplate;
848 848
 }
849 849
 
@@ -852,7 +852,7 @@  discard block
 block discarded – undo
852 852
  * All Rights Reserved.
853 853
  * Contributor(s): ______________________________________.
854 854
 */
855
- function xTemplateAssign($name, $value) {
855
+    function xTemplateAssign($name, $value) {
856 856
 
857 857
         if(!isset($this->xTemplate)) {
858 858
             $this->createXTemplate();
@@ -866,15 +866,15 @@  discard block
 block discarded – undo
866 866
  * All Rights Reserved.
867 867
  * Contributor(s): ______________________________________.
868 868
 */
869
- function getOffset($localVarName) {
870
- 	if($this->query_where_has_changed || isset($GLOBALS['record_has_changed'])) {
871
- 		$this->setSessionVariable($localVarName,"offset", 0);
872
- 	}
873
-	$offset = $this->getSessionVariable($localVarName,"offset");
874
-	if(isset($offset)) {
875
-		return $offset;
876
-	}
877
-	return 0;
869
+    function getOffset($localVarName) {
870
+        if($this->query_where_has_changed || isset($GLOBALS['record_has_changed'])) {
871
+            $this->setSessionVariable($localVarName,"offset", 0);
872
+        }
873
+    $offset = $this->getSessionVariable($localVarName,"offset");
874
+    if(isset($offset)) {
875
+        return $offset;
876
+    }
877
+    return 0;
878 878
 }
879 879
 
880 880
 /**INTERNAL FUNCTION sets the offset in the session
@@ -882,7 +882,7 @@  discard block
 block discarded – undo
882 882
  * All Rights Reserved.
883 883
  * Contributor(s): ______________________________________.
884 884
 */
885
- function setOffset($localVarName, $value) {
885
+    function setOffset($localVarName, $value) {
886 886
         $this->setSessionVariable($localVarName, "offset", $value);
887 887
 }
888 888
 
@@ -891,7 +891,7 @@  discard block
 block discarded – undo
891 891
  * All Rights Reserved.
892 892
  * Contributor(s): ______________________________________.
893 893
 */
894
- function setSessionVariable($localVarName,$varName, $value) {
894
+    function setSessionVariable($localVarName,$varName, $value) {
895 895
     $_SESSION[$this->local_current_module."_".$localVarName."_".$varName] = $value;
896 896
 }
897 897
 
@@ -906,7 +906,7 @@  discard block
 block discarded – undo
906 906
  * All Rights Reserved.
907 907
  * Contributor(s): ______________________________________.
908 908
 */
909
- function getSessionVariable($localVarName,$varName) {
909
+    function getSessionVariable($localVarName,$varName) {
910 910
     //Set any variables pass in through request first
911 911
     if(isset($_REQUEST[$this->getSessionVariableName($localVarName, $varName)])) {
912 912
         $this->setSessionVariable($localVarName,$varName,$_REQUEST[$this->getSessionVariableName($localVarName, $varName)]);
@@ -941,10 +941,10 @@  discard block
 block discarded – undo
941 941
     function calculateSortOrder($sortOrderList)
942 942
     {
943 943
         $priority_map = array(
944
-          'request',
945
-          'session',
946
-          'subpaneldefs',
947
-          'default',
944
+            'request',
945
+            'session',
946
+            'subpaneldefs',
947
+            'default',
948 948
         );
949 949
 
950 950
         foreach($priority_map as $p) {
@@ -960,33 +960,31 @@  discard block
 block discarded – undo
960 960
 
961 961
 
962 962
     /**
963
-
964
-    * @return void
965
-    * @param unknown $localVarName
966
-    * @param unknown $varName
967
-    * @desc INTERNAL FUNCTION returns the session/query variable name
968
-    * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
969
-    * All Rights Reserved.
970
-    * Contributor(s): ______________________________________..
971
-    */
963
+     * @return void
964
+     * @param unknown $localVarName
965
+     * @param unknown $varName
966
+     * @desc INTERNAL FUNCTION returns the session/query variable name
967
+     * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
968
+     * All Rights Reserved.
969
+     * Contributor(s): ______________________________________..
970
+     */
972 971
     function getSessionVariableName($localVarName,$varName) {
973 972
         return $this->local_current_module."_".$localVarName."_".$varName;
974 973
     }
975 974
 
976 975
     /**
977
-
978
-    * @return void
979
-    * @param unknown $seed
980
-    * @param unknown $xTemplateSection
981
-    * @param unknown $html_varName
982
-    * @desc INTERNAL FUNCTION Handles List Views using seeds that extend SugarBean
976
+     * @return void
977
+     * @param unknown $seed
978
+     * @param unknown $xTemplateSection
979
+     * @param unknown $html_varName
980
+     * @desc INTERNAL FUNCTION Handles List Views using seeds that extend SugarBean
983 981
         $XTemplateSection is the section in the XTemplate file that should be parsed usually main
984 982
         $html_VarName is the variable name used in the XTemplateFile e.g. TASK
985 983
         $seed is a seed that extends SugarBean
986
-        * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
987
-        * All Rights Reserved..
988
-        * Contributor(s): ______________________________________..
989
-    */
984
+     * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
985
+     * All Rights Reserved..
986
+     * Contributor(s): ______________________________________..
987
+     */
990 988
     function processSugarBean($xtemplateSection, $html_varName, $seed) {
991 989
         global $list_view_row_count;
992 990
 
@@ -1035,15 +1033,15 @@  discard block
 block discarded – undo
1035 1033
 
1036 1034
     function processUnionBeans($sugarbean, $subpanel_def, $html_var = 'CELL') {
1037 1035
 
1038
-		$last_detailview_record = $this->getSessionVariable("detailview", "record");
1039
-		if(!empty($last_detailview_record) && $last_detailview_record != $sugarbean->id){
1040
-			$GLOBALS['record_has_changed'] = true;
1041
-		}
1042
-		$this->setSessionVariable("detailview", "record", $sugarbean->id);
1036
+        $last_detailview_record = $this->getSessionVariable("detailview", "record");
1037
+        if(!empty($last_detailview_record) && $last_detailview_record != $sugarbean->id){
1038
+            $GLOBALS['record_has_changed'] = true;
1039
+        }
1040
+        $this->setSessionVariable("detailview", "record", $sugarbean->id);
1043 1041
 
1044
-		$current_offset = $this->getOffset($html_var);
1045
-		$module = isset($_REQUEST['module']) ? $_REQUEST['module'] : '';
1046
-		$response = array();
1042
+        $current_offset = $this->getOffset($html_var);
1043
+        $module = isset($_REQUEST['module']) ? $_REQUEST['module'] : '';
1044
+        $response = array();
1047 1045
 
1048 1046
         // choose sort order
1049 1047
         $sort_order = array();
@@ -1088,11 +1086,11 @@  discard block
 block discarded – undo
1088 1086
         $_SESSION['last_sub' .$this->subpanel_module. '_order'] = $this->sort_order;
1089 1087
         $_SESSION['last_sub' .$this->subpanel_module. '_url'] = $this->getBaseURL($html_var);
1090 1088
 
1091
-		// Bug 8139 - Correct Subpanel sorting on 'name', when subpanel sorting default is 'last_name, first_name'
1092
-		if (($this->sortby == 'name' || $this->sortby == 'last_name') &&
1093
-			str_replace(' ', '', trim($subpanel_def->_instance_properties['sort_by'])) == 'last_name,first_name') {
1094
-			$this->sortby = 'last_name '.$this->sort_order.', first_name ';
1095
-		}
1089
+        // Bug 8139 - Correct Subpanel sorting on 'name', when subpanel sorting default is 'last_name, first_name'
1090
+        if (($this->sortby == 'name' || $this->sortby == 'last_name') &&
1091
+            str_replace(' ', '', trim($subpanel_def->_instance_properties['sort_by'])) == 'last_name,first_name') {
1092
+            $this->sortby = 'last_name '.$this->sort_order.', first_name ';
1093
+        }
1096 1094
 
1097 1095
         if(!empty($this->response)){
1098 1096
             $response =& $this->response;
@@ -1168,15 +1166,15 @@  discard block
 block discarded – undo
1168 1166
             return $baseurl;
1169 1167
     }
1170 1168
     /**
1171
-    * @return void
1172
-    * @param unknown $data
1173
-    * @param unknown $xTemplateSection
1174
-    * @param unknown $html_varName
1175
-    * @desc INTERNAL FUNCTION process the List Navigation
1176
-    * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1177
-    * All Rights Reserved.
1178
-    * Contributor(s): ______________________________________..
1179
-    */
1169
+     * @return void
1170
+     * @param unknown $data
1171
+     * @param unknown $xTemplateSection
1172
+     * @param unknown $html_varName
1173
+     * @desc INTERNAL FUNCTION process the List Navigation
1174
+     * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1175
+     * All Rights Reserved.
1176
+     * Contributor(s): ______________________________________..
1177
+     */
1180 1178
     function processListNavigation($xtemplateSection, $html_varName, $current_offset, $next_offset, $previous_offset, $row_count, $sugarbean=null, $subpanel_def=null, $col_count = 20) {
1181 1179
 
1182 1180
         global $export_module;
@@ -1316,8 +1314,8 @@  discard block
 block discarded – undo
1316 1314
             $end_record = $end_record-1;
1317 1315
 
1318 1316
 $script_href = "<a style=\'width: 150px\' name=\"thispage\" class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'if (document.MassUpdate.select_entire_list.value==1){document.MassUpdate.select_entire_list.value=0;sListView.check_all(document.MassUpdate, \"mass[]\", true, $this->records_per_page)}else {sListView.check_all(document.MassUpdate, \"mass[]\", true)};\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_CURRENT']}&nbsp;&#x28;{$this->records_per_page}&#x29;&#x200E;</a>"
1319
- . "<a style=\'width: 150px\' name=\"selectall\" class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.check_entire_list(document.MassUpdate, \"mass[]\",true,{$row_count});\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}&nbsp;&#x28;{$row_count}&#x29;&#x200E;</a>"
1320
- . "<a style=\'width: 150px\' name=\"deselect\" class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.clear_all(document.MassUpdate, \"mass[]\", false);\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_NONE']}</a>";
1317
+    . "<a style=\'width: 150px\' name=\"selectall\" class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.check_entire_list(document.MassUpdate, \"mass[]\",true,{$row_count});\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}&nbsp;&#x28;{$row_count}&#x29;&#x200E;</a>"
1318
+    . "<a style=\'width: 150px\' name=\"deselect\" class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.clear_all(document.MassUpdate, \"mass[]\", false);\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_NONE']}</a>";
1321 1319
 
1322 1320
 $close_inline_img = SugarThemeRegistry::current()->getImage('close_inline', 'border=0', null, null, ".gif", $app_strings['LBL_CLOSEINLINE']);
1323 1321
 
@@ -1548,15 +1546,15 @@  discard block
 block discarded – undo
1548 1546
 
1549 1547
 
1550 1548
     /**
1551
-    * @return void
1552
-    * @param unknown $data
1553
-    * @param unknown $xTemplateSection
1554
-    * @param unknown $html_varName
1555
-    * @desc INTERNAL FUNCTION handles the rows
1556
-    * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1557
-    * All Rights Reserved.
1558
-    * Contributor(s): ______________________________________..
1559
-    */
1549
+     * @return void
1550
+     * @param unknown $data
1551
+     * @param unknown $xTemplateSection
1552
+     * @param unknown $html_varName
1553
+     * @desc INTERNAL FUNCTION handles the rows
1554
+     * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1555
+     * All Rights Reserved.
1556
+     * Contributor(s): ______________________________________..
1557
+     */
1560 1558
     function processListRows($data, $xtemplateSection, $html_varName)
1561 1559
     {
1562 1560
         global $odd_bg;
@@ -1753,7 +1751,7 @@  discard block
 block discarded – undo
1753 1751
         {
1754 1752
             $orderBy=  'amount';
1755 1753
         }
1756
-		$buttons = false;
1754
+        $buttons = false;
1757 1755
         $col_count = 0;
1758 1756
         foreach($subpanel_def->get_list_fields() as $column_name=>$widget_args)
1759 1757
         {
@@ -1771,17 +1769,17 @@  discard block
 block discarded – undo
1771 1769
                 }
1772 1770
 
1773 1771
                 if (!preg_match("/_button/i", $column_name)) {
1774
-	                $widget_args['name']=$column_name;
1775
-	                $widget_args['sort'] = $imgArrow;
1776
-	                $widget_args['start_link_wrapper'] = $this->start_link_wrapper;
1777
-	                $widget_args['end_link_wrapper'] = $this->end_link_wrapper;
1778
-	                $widget_args['subpanel_module'] = $this->subpanel_module;
1779
-
1780
-	                $widget_contents = $layout_manager->widgetDisplay($widget_args);
1781
-	                $cell_width = empty($widget_args['width']) ? '' : $widget_args['width'];
1782
-	                $this->xTemplate->assign('HEADER_CELL', $widget_contents);
1783
-	                static $count;
1784
-	            if(!isset($count))$count = 0; else $count++;
1772
+                    $widget_args['name']=$column_name;
1773
+                    $widget_args['sort'] = $imgArrow;
1774
+                    $widget_args['start_link_wrapper'] = $this->start_link_wrapper;
1775
+                    $widget_args['end_link_wrapper'] = $this->end_link_wrapper;
1776
+                    $widget_args['subpanel_module'] = $this->subpanel_module;
1777
+
1778
+                    $widget_contents = $layout_manager->widgetDisplay($widget_args);
1779
+                    $cell_width = empty($widget_args['width']) ? '' : $widget_args['width'];
1780
+                    $this->xTemplate->assign('HEADER_CELL', $widget_contents);
1781
+                    static $count;
1782
+                if(!isset($count))$count = 0; else $count++;
1785 1783
                     if($col_count == 0 || $column_name == 'name') $footable = 'data-toggle="true"';
1786 1784
                     else {
1787 1785
                         $footable = 'data-hide="phone"';
@@ -1789,11 +1787,11 @@  discard block
 block discarded – undo
1789 1787
                         if ($col_count > 4) $footable = 'data-hide="phone,phonelandscape,tablet"';
1790 1788
                     }
1791 1789
                     $this->xTemplate->assign('FOOTABLE', $footable);
1792
-	                $this->xTemplate->assign('CELL_COUNT', $count);
1793
-	                $this->xTemplate->assign('CELL_WIDTH', $cell_width);
1794
-	                $this->xTemplate->parse('dyn_list_view.header_cell');
1790
+                    $this->xTemplate->assign('CELL_COUNT', $count);
1791
+                    $this->xTemplate->assign('CELL_WIDTH', $cell_width);
1792
+                    $this->xTemplate->parse('dyn_list_view.header_cell');
1795 1793
                 } else {
1796
-                	$buttons = true;
1794
+                    $buttons = true;
1797 1795
                 }
1798 1796
             }
1799 1797
             ++$col_count;
@@ -1801,29 +1799,29 @@  discard block
 block discarded – undo
1801 1799
 
1802 1800
         if($buttons) {
1803 1801
                     $this->xTemplate->assign('FOOTABLE', '');
1804
-        			$this->xTemplate->assign('HEADER_CELL', "&nbsp;");
1805
-        			$this->xTemplate->assign('CELL_COUNT', $count);
1806
-	                $this->xTemplate->assign('CELL_WIDTH', $cell_width);
1807
-	                $this->xTemplate->parse('dyn_list_view.header_cell');
1802
+                    $this->xTemplate->assign('HEADER_CELL', "&nbsp;");
1803
+                    $this->xTemplate->assign('CELL_COUNT', $count);
1804
+                    $this->xTemplate->assign('CELL_WIDTH', $cell_width);
1805
+                    $this->xTemplate->parse('dyn_list_view.header_cell');
1808 1806
         }
1809 1807
 
1810 1808
     }
1811 1809
 
1812 1810
 
1813 1811
     /**
1814
-    * @return void
1815
-    * @param unknown $seed
1816
-    * @param unknown $xTemplateSection
1817
-    * @param unknown $html_varName
1818
-    * @desc PUBLIC FUNCTION Handles List Views using seeds that extend SugarBean
1812
+     * @return void
1813
+     * @param unknown $seed
1814
+     * @param unknown $xTemplateSection
1815
+     * @param unknown $html_varName
1816
+     * @desc PUBLIC FUNCTION Handles List Views using seeds that extend SugarBean
1819 1817
         $XTemplateSection is the section in the XTemplate file that should be parsed usually main
1820 1818
         $html_VarName is the variable name used in the XTemplateFile e.g. TASK
1821 1819
         $seed is a seed there are two types of seeds one is a subclass of SugarBean, the other is a list usually created from a sugar bean using get_list
1822 1820
         if no XTemplate is set it will create  a new XTemplate
1823
-        * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
1824
-        * All Rights Reserved..
1825
-        * Contributor(s): ______________________________________..
1826
-    */
1821
+     * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
1822
+     * All Rights Reserved..
1823
+     * Contributor(s): ______________________________________..
1824
+     */
1827 1825
 
1828 1826
     function processListViewTwo($seed, $xTemplateSection, $html_varName) {
1829 1827
         global $current_user;
@@ -1898,12 +1896,12 @@  discard block
 block discarded – undo
1898 1896
         return "&nbsp;<img border='0' src='".SugarThemeRegistry::current()->getImageURL("arrow{$upDown}.{$ext}")."' ";
1899 1897
     }
1900 1898
 
1901
-	function getArrowEnd() {
1902
-		$imgFileParts = pathinfo(SugarThemeRegistry::current()->getImageURL("arrow.gif"));
1899
+    function getArrowEnd() {
1900
+        $imgFileParts = pathinfo(SugarThemeRegistry::current()->getImageURL("arrow.gif"));
1903 1901
 
1904 1902
         list($width,$height) = ListView::getArrowImageSize();
1905 1903
 
1906
-		return '.'.$imgFileParts['extension']."' width='$width' height='$height' align='absmiddle' alt=".translate('LBL_SORT').">";
1904
+        return '.'.$imgFileParts['extension']."' width='$width' height='$height' align='absmiddle' alt=".translate('LBL_SORT').">";
1907 1905
     }
1908 1906
 
1909 1907
     function getArrowUpDownEnd($upDown) {
@@ -1924,9 +1922,9 @@  discard block
 block discarded – undo
1924 1922
         return " width='$width' height='$height' align='absmiddle' alt='$sortStr'>";
1925 1923
     }
1926 1924
 
1927
-	function getArrowImageSize() {
1928
-	    // jbasicChartDashletsExpColust get the non-sort image's size.. the up and down have be the same.
1929
-		$image = SugarThemeRegistry::current()->getImageURL("arrow.gif",false);
1925
+    function getArrowImageSize() {
1926
+        // jbasicChartDashletsExpColust get the non-sort image's size.. the up and down have be the same.
1927
+        $image = SugarThemeRegistry::current()->getImageURL("arrow.gif",false);
1930 1928
 
1931 1929
         $cache_key = 'arrow_size.'.$image;
1932 1930
 
@@ -1958,13 +1956,13 @@  discard block
 block discarded – undo
1958 1956
         return $result;
1959 1957
     }
1960 1958
 
1961
-	function getOrderByInfo($html_varName)
1962
-	{
1963
-		$orderBy = $this->getSessionVariable($html_varName, "OBL");
1964
-		$desc = $this->getSessionVariable($html_varName, $orderBy.'S');
1965
-		$orderBy = str_replace('.', '_', $orderBy);
1966
-		return array($orderBy,$desc);
1967
-	}
1959
+    function getOrderByInfo($html_varName)
1960
+    {
1961
+        $orderBy = $this->getSessionVariable($html_varName, "OBL");
1962
+        $desc = $this->getSessionVariable($html_varName, $orderBy.'S');
1963
+        $orderBy = str_replace('.', '_', $orderBy);
1964
+        return array($orderBy,$desc);
1965
+    }
1968 1966
 
1969 1967
     function processSortArrows($html_varName)
1970 1968
     {
@@ -1973,25 +1971,25 @@  discard block
 block discarded – undo
1973 1971
 
1974 1972
         list($orderBy,$desc) = $this->getOrderByInfo($html_varName);
1975 1973
 
1976
-		$imgArrow = "_up";
1977
-		if($desc) {
1978
-			$imgArrow = "_down";
1979
-		}
1980
-		/**
1981
-		 * @deprecated only used by legacy opportunites listview, nothing current. Leaving for BC
1982
-		 */
1983
-		if($orderBy == 'amount')
1984
-		{
1985
-			$this->xTemplateAssign('amount_arrow', $imgArrow);
1986
-		}
1987
-		else if($orderBy == 'amount_usdollar')
1988
-		{
1989
-			$this->xTemplateAssign('amount_usdollar_arrow', $imgArrow);
1990
-		}
1991
-		else
1992
-		{
1993
-			$this->xTemplateAssign($orderBy.'_arrow', $imgArrow);
1994
-		}
1974
+        $imgArrow = "_up";
1975
+        if($desc) {
1976
+            $imgArrow = "_down";
1977
+        }
1978
+        /**
1979
+         * @deprecated only used by legacy opportunites listview, nothing current. Leaving for BC
1980
+         */
1981
+        if($orderBy == 'amount')
1982
+        {
1983
+            $this->xTemplateAssign('amount_arrow', $imgArrow);
1984
+        }
1985
+        else if($orderBy == 'amount_usdollar')
1986
+        {
1987
+            $this->xTemplateAssign('amount_usdollar_arrow', $imgArrow);
1988
+        }
1989
+        else
1990
+        {
1991
+            $this->xTemplateAssign($orderBy.'_arrow', $imgArrow);
1992
+        }
1995 1993
 
1996 1994
         $this->xTemplateAssign('arrow_end', $this->getArrowEnd());
1997 1995
     }
@@ -2030,37 +2028,37 @@  discard block
 block discarded – undo
2030 2028
         return sugar_microtime();
2031 2029
     }
2032 2030
 
2033
-     /**INTERNAL FUNCTION sets a session variable keeping it local to the listview
2031
+        /**INTERNAL FUNCTION sets a session variable keeping it local to the listview
2034 2032
      not the current_module
2035 2033
      * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
2036 2034
      * All Rights Reserved.
2037 2035
      * Contributor(s): ______________________________________.
2038 2036
      */
2039
-     function setLocalSessionVariable($localVarName,$varName, $value) {
2037
+        function setLocalSessionVariable($localVarName,$varName, $value) {
2040 2038
         $_SESSION[$localVarName."_".$varName] = $value;
2041
-     }
2039
+        }
2042 2040
 
2043
-     /**INTERNAL FUNCTION returns a session variable that is local to the listview,
2041
+        /**INTERNAL FUNCTION returns a session variable that is local to the listview,
2044 2042
      not the current_module
2045 2043
      * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
2046 2044
      * All Rights Reserved.
2047 2045
      * Contributor(s): ______________________________________.
2048 2046
      */
2049
- function getLocalSessionVariable($localVarName,$varName) {
2047
+    function getLocalSessionVariable($localVarName,$varName) {
2050 2048
     if(isset($_SESSION[$localVarName."_".$varName])) {
2051 2049
         return $_SESSION[$localVarName."_".$varName];
2052 2050
     }
2053 2051
     else{
2054 2052
         return "";
2055 2053
     }
2056
- }
2054
+    }
2057 2055
 
2058
- /* Set to true if you want Additional Details to appear in the listview
2056
+    /* Set to true if you want Additional Details to appear in the listview
2059 2057
   */
2060
- function setAdditionalDetails($value = true, $function = '') {
2058
+    function setAdditionalDetails($value = true, $function = '') {
2061 2059
     if(!empty($function)) $this->additionalDetailsFunction = $function;
2062 2060
     $this->_additionalDetails = $value;
2063
- }
2061
+    }
2064 2062
 
2065 2063
 }
2066 2064
 ?>
Please login to merge, or discard this patch.