~azzar1/unity/add-show-desktop-key

443 by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0
1
<?php
2
/**
3
*
4
* @package acp
5
* @version $Id: acp_database.php,v 1.82 2007/10/05 14:36:32 acydburn Exp $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8
*
9
*/
10
11
/**
12
* @ignore
13
*/
14
if (!defined('IN_PHPBB'))
15
{
16
	exit;
17
}
18
19
/**
20
* @package acp
21
*/
22
class acp_database
23
{
24
	var $u_action;
25
26
	function main($id, $mode)
27
	{
28
		global $db, $user, $auth, $template, $table_prefix;
29
		global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
30
		
31
		$user->add_lang('acp/database');
32
33
		$this->tpl_name = 'acp_database';
34
		$this->page_title = 'ACP_DATABASE';
35
36
		$action	= request_var('action', '');
37
		$submit = (isset($_POST['submit'])) ? true : false;
38
39
		$template->assign_vars(array(
40
			'MODE'	=> $mode
41
		));
42
43
		switch ($mode)
44
		{
45
			case 'backup':
46
47
				$this->page_title = 'ACP_BACKUP';
48
49
				switch ($action)
50
				{
51
					case 'download':
52
						$type	= request_var('type', '');
53
						$table	= request_var('table', array(''));
54
						$format	= request_var('method', '');
55
						$where	= request_var('where', '');
56
57
						if (!sizeof($table))
58
						{
59
							trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
60
						}
61
62
						$store = $download = $structure = $schema_data = false;
63
64
						if ($where == 'store_and_download' || $where == 'store')
65
						{
66
							$store = true;
67
						}
68
69
						if ($where == 'store_and_download' || $where == 'download')
70
						{
71
							$download = true;
72
						}
73
74
						if ($type == 'full' || $type == 'structure')
75
						{
76
							$structure = true;
77
						}
78
79
						if ($type == 'full' || $type == 'data')
80
						{
81
							$schema_data = true;
82
						}
83
84
						@set_time_limit(1200);
85
86
						$time = time();
87
88
						$filename = 'backup_' . $time . '_' . unique_id();
89
						switch ($db->sql_layer)
90
						{
91
							case 'mysqli':
92
							case 'mysql4':
93
							case 'mysql':
94
								$extractor = new mysql_extractor($download, $store, $format, $filename, $time);
95
							break;
96
97
							case 'sqlite':
98
								$extractor = new sqlite_extractor($download, $store, $format, $filename, $time);
99
							break;
100
101
							case 'postgres':
102
								$extractor = new postgres_extractor($download, $store, $format, $filename, $time);
103
							break;
104
105
							case 'oracle':
106
								$extractor = new oracle_extractor($download, $store, $format, $filename, $time);
107
							break;
108
109
							case 'mssql':
110
							case 'mssql_odbc':
111
								$extractor = new mssql_extractor($download, $store, $format, $filename, $time);
112
							break;
113
114
							case 'firebird':
115
								$extractor = new firebird_extractor($download, $store, $format, $filename, $time);
116
							break;
117
						}
118
119
						$extractor->write_start($table_prefix);
120
121
						foreach ($table as $table_name)
122
						{
123
							// Get the table structure
124
							if ($structure)
125
							{
126
								$extractor->write_table($table_name);
127
							}
128
							else
129
							{
130
								// We might wanna empty out all that junk :D
131
								switch ($db->sql_layer)
132
								{
133
									case 'sqlite':
134
									case 'firebird':
135
										$extractor->flush('DELETE FROM ' . $table_name . ";\n");
136
									break;
137
138
									case 'mssql':
139
									case 'mssql_odbc':
140
										$extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
141
									break;
142
143
									case 'oracle':
144
										$extractor->flush('TRUNCATE TABLE ' . $table_name . "\\\n");
145
									break;
146
147
									default:
148
										$extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
149
									break;
150
								}
151
							}
152
153
							// Data
154
							if ($schema_data)
155
							{
156
								$extractor->write_data($table_name);
157
							}
158
						}
159
160
						$extractor->write_end();
161
162
						if ($download == true)
163
						{
164
							exit;
165
						}
166
167
						add_log('admin', 'LOG_DB_BACKUP');
168
						trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
169
					break;
170
171
					default:
172
						include($phpbb_root_path . 'includes/functions_install.' . $phpEx);
173
						$tables = get_tables($db);
174
						foreach ($tables as $table_name)
175
						{
176
							if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
177
							{
178
								$template->assign_block_vars('tables', array(
179
									'TABLE'	=> $table_name
180
								));
181
							}
182
						}
183
						unset($tables);
184
185
						$template->assign_vars(array(
186
							'U_ACTION'	=> $this->u_action . '&amp;action=download'
187
						));
188
						
189
						$available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
190
191
						foreach ($available_methods as $type => $module)
192
						{
193
							if (!@extension_loaded($module))
194
							{
195
								continue;
196
							}
197
198
							$template->assign_block_vars('methods', array(
199
								'TYPE'	=> $type
200
							));
201
						}
202
203
						$template->assign_block_vars('methods', array(
204
							'TYPE'	=> 'text'
205
						));
206
					break;
207
				}
208
			break;
209
210
			case 'restore':
211
212
				$this->page_title = 'ACP_RESTORE';
213
214
				switch ($action)
215
				{
216
					case 'submit':
217
						$delete = request_var('delete', '');
218
						$file = request_var('file', '');
219
220
						if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
221
						{
222
							trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
223
						}
224
225
						$file_name = $phpbb_root_path . 'store/' . $matches[0];
226
227
						if (!file_exists($file_name) || !is_readable($file_name))
228
						{
229
							trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
230
						}
231
232
						if ($delete)
233
						{
234
							if (confirm_box(true))
235
							{
236
								unlink($file_name);
237
								add_log('admin', 'LOG_DB_DELETE');
238
								trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
239
							}
240
							else
241
							{
242
								confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
243
							}
244
						}
245
						else
246
						{
247
							$download = request_var('download', '');
248
249
							if ($download)
250
							{
251
								$name = $matches[0];
252
253
								switch ($matches[1])
254
								{
255
									case 'sql':
256
										$mimetype = 'text/x-sql';
257
									break;
258
									case 'sql.bz2':
259
										$mimetype = 'application/x-bzip2';
260
									break;
261
									case 'sql.gz':
262
										$mimetype = 'application/x-gzip';
263
									break;
264
								}
265
266
								header('Pragma: no-cache');
267
								header("Content-Type: $mimetype; name=\"$name\"");
268
								header("Content-disposition: attachment; filename=$name");
269
270
								@set_time_limit(0);
271
272
								$fp = @fopen($file_name, 'rb');
273
274
								if ($fp !== false)
275
								{
276
									while (!feof($fp))
277
									{
278
										echo fread($fp, 8192);
279
									}
280
									fclose($fp);
281
								}
282
283
								flush();
284
								exit;
285
							}
286
287
							switch ($matches[1])
288
							{
289
								case 'sql':
290
									$fp = fopen($file_name, 'rb');
291
									$read = 'fread';
292
									$seek = 'fseek';
293
									$eof = 'feof';
294
									$close = 'fclose';
295
									$fgetd = 'fgetd';
296
								break;
297
298
								case 'sql.bz2':
299
									$fp = bzopen($file_name, 'r');
300
									$read = 'bzread';
301
									$seek = '';
302
									$eof = 'feof';
303
									$close = 'bzclose';
304
									$fgetd = 'fgetd_seekless';
305
								break;
306
307
								case 'sql.gz':
308
									$fp = gzopen($file_name, 'rb');
309
									$read = 'gzread';
310
									$seek = 'gzseek';
311
									$eof = 'gzeof';
312
									$close = 'gzclose';
313
									$fgetd = 'fgetd';
314
								break;
315
							}
316
317
							switch ($db->sql_layer)
318
							{
319
								case 'mysql':
320
								case 'mysql4':
321
								case 'mysqli':
322
								case 'sqlite':
323
									while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
324
									{
325
										$db->sql_query($sql);
326
									}
327
								break;
328
329
								case 'firebird':
330
									$delim = ";\n";
331
									while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
332
									{
333
										$query = trim($sql);
334
										if (substr($query, 0, 8) === 'SET TERM')
335
										{
336
											$delim = $query[9] . "\n";
337
											continue;
338
										}
339
										$db->sql_query($query);
340
									}
341
								break;
342
343
								case 'postgres':
344
									while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
345
									{
346
										$query = trim($sql);
347
										$db->sql_query($query);
348
										if (substr($query, 0, 4) == 'COPY')
349
										{
350
											while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
351
											{
352
												if ($sub === false)
353
												{
354
													trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
355
												}
356
												pg_put_line($db->db_connect_id, $sub . "\n");
357
											}
358
											pg_put_line($db->db_connect_id, "\\.\n");
359
											pg_end_copy($db->db_connect_id);
360
										}
361
									}
362
								break;
363
364
								case 'oracle':
365
									while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
366
									{
367
										$db->sql_query($sql);
368
									}
369
								break;
370
371
								case 'mssql':
372
								case 'mssql_odbc':
373
									while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
374
									{
375
										$db->sql_query($sql);
376
									}
377
								break;
378
							}
379
380
							$close($fp);
381
382
							add_log('admin', 'LOG_DB_RESTORE');
383
							trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
384
							break;
385
						}
386
387
					default:
388
						$methods = array('sql');
389
						$available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
390
391
						foreach ($available_methods as $type => $module)
392
						{
393
							if (!@extension_loaded($module))
394
							{
395
								continue;
396
							}
397
							$methods[] = $type;
398
						}
399
400
						$dir = $phpbb_root_path . 'store/';
401
						$dh = @opendir($dir);
402
403
						if ($dh)
404
						{
405
							while (($file = readdir($dh)) !== false)
406
							{
407
								if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
408
								{
409
									$supported = in_array($matches[2], $methods);
410
411
									if ($supported == 'true')
412
									{
413
										$template->assign_block_vars('files', array(
414
											'FILE'		=> $file,
415
											'NAME'		=> gmdate("d-m-Y H:i:s", $matches[1]),
416
											'SUPPORTED'	=> $supported
417
										));
418
									}
419
								}
420
							}
421
							closedir($dh);
422
						}
423
424
						$template->assign_vars(array(
425
							'U_ACTION'	=> $this->u_action . '&amp;action=submit'
426
						));
427
					break;
428
				}
429
			break;
430
		}
431
	}
432
}
433
434
/**
435
* @package acp
436
*/
437
class base_extractor
438
{
439
	var $fh;
440
	var $fp;
441
	var $write;
442
	var $close;
443
	var $store;
444
	var $download;
445
	var $time;
446
	var $format;
447
	var $run_comp = false;
448
449
	function base_extractor($download = false, $store = false, $format, $filename, $time)
450
	{
451
		$this->download = $download;
452
		$this->store = $store;
453
		$this->time = $time;
454
		$this->format = $format;
455
456
		switch ($format)
457
		{
458
			case 'text':
459
				$ext = '.sql';
460
				$open = 'fopen';
461
				$this->write = 'fwrite';
462
				$this->close = 'fclose';
463
				$mimetype = 'text/x-sql';
464
			break;
465
			case 'bzip2':
466
				$ext = '.sql.bz2';
467
				$open = 'bzopen';
468
				$this->write = 'bzwrite';
469
				$this->close = 'bzclose';
470
				$mimetype = 'application/x-bzip2';
471
			break;
472
			case 'gzip':
473
				$ext = '.sql.gz';
474
				$open = 'gzopen';
475
				$this->write = 'gzwrite';
476
				$this->close = 'gzclose';
477
				$mimetype = 'application/x-gzip';
478
			break;
479
		}
480
481
		if ($download == true)
482
		{
483
			$name = $filename . $ext;
484
			header('Pragma: no-cache');
485
			header("Content-Type: $mimetype; name=\"$name\"");
486
			header("Content-disposition: attachment; filename=$name");
487
	
488
			switch ($format)
489
			{
490
				case 'bzip2':
491
					ob_start();
492
				break;
493
494
				case 'gzip':
495
					if ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'msie') === false)
496
					{
497
						ob_start('ob_gzhandler');
498
					}
499
					else
500
					{
501
						$this->run_comp = true;
502
					}
503
				break;
504
			}
505
		}
506
		
507
		if ($store == true)
508
		{
509
			global $phpbb_root_path;
510
			$file = $phpbb_root_path . 'store/' . $filename . $ext;
511
	
512
			$this->fp = $open($file, 'w');
513
	
514
			if (!$this->fp)
515
			{
516
				trigger_error('Unable to write temporary file to storage folder', E_USER_ERROR);
517
			}
518
		}
519
	}
520
521
	function write_end()
522
	{
523
		static $close;
524
		if ($this->store)
525
		{
526
			if ($close === null)
527
			{
528
				$close = $this->close;
529
			}
530
			$close($this->fp);
531
		}
532
533
		// bzip2 must be written all the way at the end
534
		if ($this->download && $this->format === 'bzip2')
535
		{
536
			$c = ob_get_clean();
537
			echo bzcompress($c);
538
		}
539
	}
540
541
	function flush($data)
542
	{
543
		static $write;
544
		if ($this->store === true)
545
		{
546
			if ($write === null)
547
			{
548
				$write = $this->write;
549
			}
550
			$write($this->fp, $data);
551
		}
552
553
		if ($this->download === true)
554
		{
555
			if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp))
556
			{
557
				echo $data;
558
			}
559
560
			// we can write the gzip data as soon as we get it
561
			if ($this->format === 'gzip')
562
			{
563
				if ($this->run_comp)
564
				{
565
					echo gzencode($data);
566
				}
567
				else
568
				{
569
					ob_flush();
570
					flush();
571
				}
572
			}
573
		}
574
	}
575
}
576
577
/**
578
* @package acp
579
*/
580
class mysql_extractor extends base_extractor
581
{
582
	function write_start($table_prefix)
583
	{
584
		$sql_data = "#\n";
585
		$sql_data .= "# phpBB Backup Script\n";
586
		$sql_data .= "# Dump of tables for $table_prefix\n";
587
		$sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
588
		$sql_data .= "#\n";
589
		$this->flush($sql_data);
590
	}
591
592
	function write_table($table_name)
593
	{
594
		global $db;
595
		static $new_extract;
596
597
		if ($new_extract === null)
598
		{
599
			if ($db->sql_layer === 'mysqli' || version_compare($db->mysql_version, '3.23.20', '>='))
600
			{
601
				$new_extract = true;
602
			}
603
			else
604
			{
605
				$new_extract = false;
606
			}
607
		}
608
609
		if ($new_extract)
610
		{
611
			$this->new_write_table($table_name);
612
		}
613
		else
614
		{
615
			$this->old_write_table($table_name);
616
		}
617
	}
618
619
	function write_data($table_name)
620
	{
621
		global $db;
622
		if ($db->sql_layer === 'mysqli')
623
		{
624
			$this->write_data_mysqli($table_name);
625
		}
626
		else
627
		{
628
			$this->write_data_mysql($table_name);
629
		}
630
	}
631
632
	function write_data_mysqli($table_name)
633
	{
634
		global $db;
635
		$sql = "SELECT *
636
			FROM $table_name";
637
		$result = mysqli_query($db->db_connect_id, $sql, MYSQLI_USE_RESULT);
638
		if ($result != false)
639
		{
640
			$fields_cnt = mysqli_num_fields($result);
641
		
642
			// Get field information
643
			$field = mysqli_fetch_fields($result);
644
			$field_set = array();
645
		
646
			for ($j = 0; $j < $fields_cnt; $j++)
647
			{
648
				$field_set[] = $field[$j]->name;
649
			}
650
651
			$search			= array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
652
			$replace		= array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
653
			$fields			= implode(', ', $field_set);
654
			$sql_data		= 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
655
			$first_set		= true;
656
			$query_len		= 0;
657
			$max_len		= get_usable_memory();
658
		
659
			while ($row = mysqli_fetch_row($result))
660
			{
661
				$values	= array();
662
				if ($first_set)
663
				{
664
					$query = $sql_data . '(';
665
				}
666
				else
667
				{
668
					$query  .= ',(';
669
				}
670
671
				for ($j = 0; $j < $fields_cnt; $j++)
672
				{
673
					if (!isset($row[$j]) || is_null($row[$j]))
674
					{
675
						$values[$j] = 'NULL';
676
					}
677
					else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024))
678
					{
679
						$values[$j] = $row[$j];
680
					}
681
					else
682
					{
683
						$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
684
					}
685
				}
686
				$query .= implode(', ', $values) . ')';
687
688
				$query_len += strlen($query);
689
				if ($query_len > $max_len)
690
				{
691
					$this->flush($query . ";\n\n");
692
					$query = '';
693
					$query_len = 0;
694
					$first_set = true;
695
				}
696
				else
697
				{
698
					$first_set = false;
699
				}
700
			}
701
			mysqli_free_result($result);
702
703
			// check to make sure we have nothing left to flush
704
			if (!$first_set && $query)
705
			{
706
				$this->flush($query . ";\n\n");
707
			}
708
		}
709
	}
710
711
	function write_data_mysql($table_name)
712
	{
713
		global $db;
714
		$sql = "SELECT *
715
			FROM $table_name";
716
		$result = mysql_unbuffered_query($sql, $db->db_connect_id);
717
718
		if ($result != false)
719
		{
720
			$fields_cnt = mysql_num_fields($result);
721
722
			// Get field information
723
			$field = array();
724
			for ($i = 0; $i < $fields_cnt; $i++)
725
			{
726
				$field[] = mysql_fetch_field($result, $i);
727
			}
728
			$field_set = array();
729
			
730
			for ($j = 0; $j < $fields_cnt; $j++)
731
			{
732
				$field_set[] = $field[$j]->name;
733
			}
734
735
			$search			= array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
736
			$replace		= array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
737
			$fields			= implode(', ', $field_set);
738
			$sql_data		= 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
739
			$first_set		= true;
740
			$query_len		= 0;
741
			$max_len		= get_usable_memory();
742
743
			while ($row = mysql_fetch_row($result))
744
			{
745
				$values = array();
746
				if ($first_set)
747
				{
748
					$query = $sql_data . '(';
749
				}
750
				else
751
				{
752
					$query  .= ',(';
753
				}
754
755
				for ($j = 0; $j < $fields_cnt; $j++)
756
				{
757
					if (!isset($row[$j]) || is_null($row[$j]))
758
					{
759
						$values[$j] = 'NULL';
760
					}
761
					else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
762
					{
763
						$values[$j] = $row[$j];
764
					}
765
					else
766
					{
767
						$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
768
					}
769
				}
770
				$query .= implode(', ', $values) . ')';
771
772
				$query_len += strlen($query);
773
				if ($query_len > $max_len)
774
				{
775
					$this->flush($query . ";\n\n");
776
					$query = '';
777
					$query_len = 0;
778
					$first_set = true;
779
				}
780
				else
781
				{
782
					$first_set = false;
783
				}
784
			}
785
			mysql_free_result($result);
786
787
			// check to make sure we have nothing left to flush
788
			if (!$first_set && $query)
789
			{
790
				$this->flush($query . ";\n\n");
791
			}
792
		}
793
	}
794
795
	function new_write_table($table_name)
796
	{
797
		global $db;
798
799
		$sql = 'SHOW CREATE TABLE ' . $table_name;
800
		$result = $db->sql_query($sql);
801
		$row = $db->sql_fetchrow($result);
802
803
		$sql_data = '# Table: ' . $table_name . "\n";
804
		$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
805
		$this->flush($sql_data . $row['Create Table'] . ";\n\n");
806
807
		$db->sql_freeresult($result);
808
	}
809
810
	function old_write_table($table_name)
811
	{
812
		global $db;
813
814
		$sql_data = '# Table: ' . $table_name . "\n";
815
		$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
816
		$sql_data .= "CREATE TABLE $table_name(\n";
817
		$rows = array();
818
819
		$sql = "SHOW FIELDS
820
			FROM $table_name";
821
		$result = $db->sql_query($sql);
822
823
		while ($row = $db->sql_fetchrow($result))
824
		{
825
			$line = '   ' . $row['Field'] . ' ' . $row['Type'];
826
827
			if (!is_null($row['Default']))
828
			{
829
				$line .= " DEFAULT '{$row['Default']}'";
830
			}
831
832
			if ($row['Null'] != 'YES')
833
			{
834
				$line .= ' NOT NULL';
835
			}
836
837
			if ($row['Extra'] != '')
838
			{
839
				$line .= ' ' . $row['Extra'];
840
			}
841
842
			$rows[] = $line;
843
		}
844
		$db->sql_freeresult($result);
845
846
		$sql = "SHOW KEYS
847
			FROM $table_name";
848
849
		$result = $db->sql_query($sql);
850
851
		$index = array();
852
		while ($row = $db->sql_fetchrow($result))
853
		{
854
			$kname = $row['Key_name'];
855
856
			if ($kname != 'PRIMARY')
857
			{
858
				if ($row['Non_unique'] == 0)
859
				{
860
					$kname = "UNIQUE|$kname";
861
				}
862
			}
863
864
			if ($row['Sub_part'])
865
			{
866
				$row['Column_name'] .= '(' . $row['Sub_part'] . ')';
867
			}
868
			$index[$kname][] = $row['Column_name'];
869
		}
870
		$db->sql_freeresult($result);
871
872
		foreach ($index as $key => $columns)
873
		{
874
			$line = '   ';
875
876
			if ($key == 'PRIMARY')
877
			{
878
				$line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')';
879
			}
880
			else if (strpos($key, 'UNIQUE') === 0)
881
			{
882
				$line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')';
883
			}
884
			else if (strpos($key, 'FULLTEXT') === 0)
885
			{
886
				$line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')';
887
			}
888
			else
889
			{
890
				$line .= "KEY $key (" . implode(', ', $columns) . ')';
891
			}
892
893
			$rows[] = $line;
894
		}
895
896
		$sql_data .= implode(",\n", $rows);
897
		$sql_data .= "\n);\n\n";
898
899
		$this->flush($sql_data);
900
	}
901
}
902
903
/**
904
* @package acp
905
*/
906
class sqlite_extractor extends base_extractor
907
{
908
	function write_start($prefix)
909
	{
910
		$sql_data = "--\n";
911
		$sql_data .= "-- phpBB Backup Script\n";
912
		$sql_data .= "-- Dump of tables for $prefix\n";
913
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
914
		$sql_data .= "--\n";
915
		$sql_data .= "BEGIN TRANSACTION;\n";
916
		$this->flush($sql_data);
917
	}
918
919
	function write_table($table_name)
920
	{
921
		global $db;
922
		$sql_data = '-- Table: ' . $table_name . "\n";
923
		$sql_data .= "DROP TABLE $table_name;\n";
924
925
		$sql = "SELECT sql
926
			FROM sqlite_master
927
			WHERE type = 'table'
928
				AND name = '" . $db->sql_escape($table_name) . "'
929
			ORDER BY type DESC, name;";
930
		$result = $db->sql_query($sql);
931
		$row = $db->sql_fetchrow($result);
932
		$db->sql_freeresult($result);
933
934
		// Create Table
935
		$sql_data .= $row['sql'] . ";\n";
936
937
		$result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
938
939
		$ar = array();
940
		while ($row = $db->sql_fetchrow($result))
941
		{
942
			$ar[] = $row;
943
		}
944
		$db->sql_freeresult($result);
945
		
946
		foreach ($ar as $value)
947
		{
948
			if (strpos($value['name'], 'autoindex') !== false)
949
			{
950
				continue;
951
			}
952
953
			$result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
954
955
			$fields = array();
956
			while ($row = $db->sql_fetchrow($result))
957
			{
958
				$fields[] = $row['name'];
959
			}
960
			$db->sql_freeresult($result);
961
962
			$sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
963
		}
964
965
		$this->flush($sql_data . "\n");
966
	}
967
968
	function write_data($table_name)
969
	{
970
		global $db;
971
		static $proper;
972
973
		if (is_null($proper))
974
		{
975
			$proper = version_compare(PHP_VERSION, '5.1.3', '>=');
976
		}
977
978
		if ($proper)
979
		{
980
			$col_types = sqlite_fetch_column_types($db->db_connect_id, $table_name);
981
		}
982
		else
983
		{
984
			$sql = "SELECT sql
985
				FROM sqlite_master
986
				WHERE type = 'table'
987
					AND name = '" . $table_name . "'";
988
			$table_data = sqlite_single_query($db->db_connect_id, $sql);
989
			$table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data);
990
			$table_data = trim($table_data);
991
992
			preg_match('#\((.*)\)#s', $table_data, $matches);
993
994
			$table_cols = explode(',', trim($matches[1]));
995
			foreach ($table_cols as $declaration)
996
			{
997
				$entities = preg_split('#\s+#', trim($declaration));
998
				$column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]);
999
1000
				// Hit a primary key, those are not what we need :D
1001
				if (empty($entities[1]) || (strtolower($entities[0]) === 'primary' && strtolower($entities[1]) === 'key'))
1002
				{
1003
					continue;
1004
				}
1005
				$col_types[$column_name] = $entities[1];
1006
			}
1007
		}
1008
1009
		$sql = "SELECT *
1010
			FROM $table_name";
1011
		$result = sqlite_unbuffered_query($db->db_connect_id, $sql);
1012
		$rows = sqlite_fetch_all($result, SQLITE_ASSOC);
1013
		$sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
1014
		foreach ($rows as $row)
1015
		{
1016
			foreach ($row as $column_name => $column_data)
1017
			{
1018
				if (is_null($column_data))
1019
				{
1020
					$row[$column_name] = 'NULL';
1021
				}
1022
				else if ($column_data == '')
1023
				{
1024
					$row[$column_name] = "''";
1025
				}
1026
				else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false)
1027
				{
1028
					$row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
1029
				}
1030
			}
1031
			$this->flush($sql_insert . implode(', ', $row) . ");\n");
1032
		}
1033
	}
1034
1035
	function write_end()
1036
	{
1037
		$this->flush("COMMIT;\n");
1038
		parent::write_end();
1039
	}
1040
}
1041
1042
/**
1043
* @package acp
1044
*/
1045
class postgres_extractor extends base_extractor
1046
{
1047
	function write_start($prefix)
1048
	{
1049
		$sql_data = "--\n";
1050
		$sql_data .= "-- phpBB Backup Script\n";
1051
		$sql_data .= "-- Dump of tables for $prefix\n";
1052
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1053
		$sql_data .= "--\n";
1054
		$sql_data .= "BEGIN TRANSACTION;\n";
1055
		$this->flush($sql_data);
1056
	}
1057
1058
	function write_table($table_name)
1059
	{
1060
		global $db;
1061
		static $domains_created = array();
1062
1063
		$sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
1064
			FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
1065
			WHERE a.domain_name = b.domain_name
1066
				AND b.table_name = '{$table_name}'";
1067
		$result = $db->sql_query($sql);
1068
		while ($row = $db->sql_fetchrow($result))
1069
		{
1070
			if (empty($domains_created[$row['domain_name']]))
1071
			{
1072
				$domains_created[$row['domain_name']] = true;
1073
				//$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
1074
				$sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
1075
				if (!empty($row['character_maximum_length']))
1076
				{
1077
					$sql_data .= '(' . $row['character_maximum_length'] . ')';
1078
				}
1079
				$sql_data .= ' NOT NULL';
1080
				if (!empty($row['domain_default']))
1081
				{
1082
					$sql_data .= ' DEFAULT ' . $row['domain_default'];
1083
				}
1084
				$this->flush($sql_data . ";\n");
1085
			}
1086
		}
1087
1088
		$sql_data = '-- Table: ' . $table_name . "\n";
1089
		//$sql_data .= "DROP TABLE $table_name;\n";
1090
		// PGSQL does not "tightly" bind sequences and tables, we must guess...
1091
		$sql = "SELECT relname
1092
			FROM pg_class
1093
			WHERE relkind = 'S'
1094
				AND relname = '{$table_name}_seq'";
1095
		$result = $db->sql_query($sql);
1096
		// We don't even care about storing the results. We already know the answer if we get rows back.
1097
		if ($db->sql_fetchrow($result))
1098
		{
1099
			$sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
1100
			$sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
1101
		}
1102
		$db->sql_freeresult($result);
1103
	
1104
		$field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull
1105
			FROM pg_class c, pg_attribute a, pg_type t
1106
			WHERE c.relname = '" . $db->sql_escape($table_name) . "'
1107
				AND a.attnum > 0
1108
				AND a.attrelid = c.oid
1109
				AND a.atttypid = t.oid
1110
			ORDER BY a.attnum";
1111
		$result = $db->sql_query($field_query);
1112
1113
		$sql_data .= "CREATE TABLE $table_name(\n";
1114
		$lines = array();
1115
		while ($row = $db->sql_fetchrow($result))
1116
		{
1117
			// Get the data from the table
1118
			$sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1119
				FROM pg_attrdef d, pg_class c
1120
				WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
1121
					AND (c.oid = d.adrelid)
1122
					AND d.adnum = " . $row['attnum'];
1123
			$def_res = $db->sql_query($sql_get_default);
1124
1125
			if (!$def_res)
1126
			{
1127
				unset($row['rowdefault']);
1128
			}
1129
			else
1130
			{
1131
				$row['rowdefault'] = $db->sql_fetchfield('rowdefault', false, $def_res);
1132
			}
1133
			$db->sql_freeresult($def_res);
1134
1135
			if ($row['type'] == 'bpchar')
1136
			{
1137
				// Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
1138
				$row['type'] = 'char';
1139
			}
1140
1141
			$line = '  ' . $row['field'] . ' ' . $row['type'];
1142
1143
			if (strpos($row['type'], 'char') !== false)
1144
			{
1145
				if ($row['lengthvar'] > 0)
1146
				{
1147
					$line .= '(' . ($row['lengthvar'] - 4) . ')';
1148
				}
1149
			}
1150
1151
			if (strpos($row['type'], 'numeric') !== false)
1152
			{
1153
				$line .= '(';
1154
				$line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
1155
				$line .= ')';
1156
			}
1157
1158
			if (!empty($row['rowdefault']))
1159
			{
1160
				$line .= ' DEFAULT ' . $row['rowdefault'];
1161
			}
1162
1163
			if ($row['notnull'] == 't')
1164
			{
1165
				$line .= ' NOT NULL';
1166
			}
1167
			
1168
			$lines[] = $line;
1169
		}
1170
		$db->sql_freeresult($result);
1171
1172
1173
		// Get the listing of primary keys.
1174
		$sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key
1175
			FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
1176
			WHERE (bc.oid = i.indrelid)
1177
				AND (ic.oid = i.indexrelid)
1178
				AND (ia.attrelid = i.indexrelid)
1179
				AND	(ta.attrelid = bc.oid)
1180
				AND (bc.relname = '" . $db->sql_escape($table_name) . "')
1181
				AND (ta.attrelid = i.indrelid)
1182
				AND (ta.attnum = i.indkey[ia.attnum-1])
1183
			ORDER BY index_name, tab_name, column_name";
1184
1185
		$result = $db->sql_query($sql_pri_keys);
1186
1187
		$index_create = $index_rows = $primary_key = array();
1188
1189
		// We do this in two steps. It makes placing the comma easier
1190
		while ($row = $db->sql_fetchrow($result))
1191
		{
1192
			if ($row['primary_key'] == 't')
1193
			{
1194
				$primary_key[] = $row['column_name'];
1195
				$primary_key_name = $row['index_name'];
1196
			}
1197
			else
1198
			{
1199
				// We have to store this all this info because it is possible to have a multi-column key...
1200
				// we can loop through it again and build the statement
1201
				$index_rows[$row['index_name']]['table'] = $table_name;
1202
				$index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false;
1203
				$index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
1204
			}
1205
		}
1206
		$db->sql_freeresult($result);
1207
1208
		if (!empty($index_rows))
1209
		{
1210
			foreach ($index_rows as $idx_name => $props)
1211
			{
1212
				$index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
1213
			}
1214
		}
1215
1216
		if (!empty($primary_key))
1217
		{
1218
			$lines[] = "  CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
1219
		}
1220
1221
		// Generate constraint clauses for CHECK constraints
1222
		$sql_checks = "SELECT conname as index_name, consrc
1223
			FROM pg_constraint, pg_class bc
1224
			WHERE conrelid = bc.oid
1225
				AND bc.relname = '" . $db->sql_escape($table_name) . "'
1226
				AND NOT EXISTS (
1227
					SELECT *
1228
						FROM pg_constraint as c, pg_inherits as i
1229
						WHERE i.inhrelid = pg_constraint.conrelid
1230
							AND c.conname = pg_constraint.conname
1231
							AND c.consrc = pg_constraint.consrc
1232
							AND c.conrelid = i.inhparent
1233
				)";
1234
		$result = $db->sql_query($sql_checks);
1235
1236
		// Add the constraints to the sql file.
1237
		while ($row = $db->sql_fetchrow($result))
1238
		{
1239
			if (!is_null($row['consrc']))
1240
			{
1241
				$lines[] = '  CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
1242
			}
1243
		}
1244
		$db->sql_freeresult($result);
1245
1246
		$sql_data .= implode(", \n", $lines);
1247
		$sql_data .= "\n);\n";
1248
1249
		if (!empty($index_create))
1250
		{
1251
			$sql_data .= implode("\n", $index_create) . "\n\n";
1252
		}
1253
		$this->flush($sql_data);
1254
	}
1255
1256
	function write_data($table_name)
1257
	{
1258
		global $db;
1259
		// Grab all of the data from current table.
1260
		$sql = "SELECT *
1261
			FROM $table_name";
1262
		$result = $db->sql_query($sql);
1263
1264
		$i_num_fields = pg_num_fields($result);
1265
		$seq = '';
1266
1267
		for ($i = 0; $i < $i_num_fields; $i++)
1268
		{
1269
			$ary_type[] = pg_field_type($result, $i);
1270
			$ary_name[] = pg_field_name($result, $i);
1271
1272
1273
			$sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1274
				FROM pg_attrdef d, pg_class c
1275
				WHERE (c.relname = '{$table_name}')
1276
					AND (c.oid = d.adrelid)
1277
					AND d.adnum = " . strval($i + 1);
1278
			$result2 = $db->sql_query($sql);
1279
			if ($row = $db->sql_fetchrow($result2))
1280
			{
1281
				// Determine if we must reset the sequences
1282
				if (strpos($row['rowdefault'], "nextval('") === 0)
1283
				{
1284
					$seq .= "SELECT SETVAL('{$table_name}_seq',(select case when max({$ary_name[$i]})>0 then max({$ary_name[$i]})+1 else 1 end FROM {$table_name}));\n";
1285
				}
1286
			}
1287
		}
1288
1289
		$this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
1290
		while ($row = $db->sql_fetchrow($result))
1291
		{
1292
			$schema_vals = array();
1293
1294
			// Build the SQL statement to recreate the data.
1295
			for ($i = 0; $i < $i_num_fields; $i++)
1296
			{
1297
				$str_val = $row[$ary_name[$i]];
1298
1299
				if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
1300
				{
1301
					$str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
1302
					$str_empty = '';
1303
				}
1304
				else
1305
				{
1306
					$str_empty = '\N';
1307
				}
1308
1309
				if (empty($str_val) && $str_val !== '0')
1310
				{
1311
					$str_val = $str_empty;
1312
				}
1313
1314
				$schema_vals[] = $str_val;
1315
			}
1316
1317
			// Take the ordered fields and their associated data and build it
1318
			// into a valid sql statement to recreate that field in the data.
1319
			$this->flush(implode("\t", $schema_vals) . "\n");
1320
		}
1321
		$db->sql_freeresult($result);
1322
		$this->flush("\\.\n");
1323
1324
		// Write out the sequence statements
1325
		$this->flush($seq);
1326
	}
1327
1328
	function write_end()
1329
	{
1330
		$this->flush("COMMIT;\n");
1331
		parent::write_end();
1332
	}
1333
}
1334
1335
/**
1336
* @package acp
1337
*/
1338
class mssql_extractor extends base_extractor
1339
{
1340
	function write_end()
1341
	{
1342
		$this->flush("COMMIT\nGO\n");
1343
		parent::write_end();
1344
	}
1345
1346
	function write_start($prefix)
1347
	{
1348
		$sql_data = "--\n";
1349
		$sql_data .= "-- phpBB Backup Script\n";
1350
		$sql_data .= "-- Dump of tables for $prefix\n";
1351
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1352
		$sql_data .= "--\n";
1353
		$sql_data .= "BEGIN TRANSACTION\n";
1354
		$sql_data .= "GO\n";
1355
		$this->flush($sql_data);
1356
	}
1357
1358
	function write_table($table_name)
1359
	{
1360
		global $db;
1361
		$sql_data = '-- Table: ' . $table_name . "\n";
1362
		$sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
1363
		$sql_data .= "DROP TABLE $table_name;\n";
1364
		$sql_data .= "GO\n";
1365
		$sql_data .= "\nCREATE TABLE [$table_name] (\n";
1366
		$rows = array();
1367
	
1368
		$text_flag = false;
1369
	
1370
		$sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
1371
			FROM INFORMATION_SCHEMA.COLUMNS
1372
			WHERE TABLE_NAME = '$table_name'";
1373
		$result = $db->sql_query($sql);
1374
	
1375
		while ($row = $db->sql_fetchrow($result))
1376
		{
1377
			$line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
1378
	
1379
			if ($row['DATA_TYPE'] == 'text')
1380
			{
1381
				$text_flag = true;
1382
			}
1383
	
1384
			if ($row['IS_IDENTITY'])
1385
			{
1386
				$line .= ' IDENTITY (1 , 1)';
1387
			}
1388
	
1389
			if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
1390
			{
1391
				$line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
1392
			}
1393
	
1394
			if ($row['IS_NULLABLE'] == 'YES')
1395
			{
1396
				$line .= ' NULL';
1397
			}
1398
			else
1399
			{
1400
				$line .= ' NOT NULL';
1401
			}
1402
	
1403
			if ($row['COLUMN_DEFAULT'])
1404
			{
1405
				$line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
1406
			}
1407
	
1408
			$rows[] = $line;
1409
		}
1410
		$db->sql_freeresult($result);
1411
	
1412
		$sql_data .= implode(",\n", $rows);
1413
		$sql_data .= "\n) ON [PRIMARY]";
1414
	
1415
		if ($text_flag)
1416
		{
1417
			$sql_data .= " TEXTIMAGE_ON [PRIMARY]";
1418
		}
1419
	
1420
		$sql_data .= "\nGO\n\n";
1421
		$rows = array();
1422
	
1423
		$sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
1424
			FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
1425
			WHERE TABLE_NAME = '$table_name'";
1426
		$result = $db->sql_query($sql);
1427
		while ($row = $db->sql_fetchrow($result))
1428
		{
1429
			if (!sizeof($rows))
1430
			{
1431
				$sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
1432
				$sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY  CLUSTERED \n\t(\n";
1433
			}
1434
			$rows[] = "\t\t[{$row['COLUMN_NAME']}]";
1435
		}
1436
		if (sizeof($rows))
1437
		{
1438
			$sql_data .= implode(",\n", $rows);
1439
			$sql_data .= "\n\t)  ON [PRIMARY] \nGO\n";
1440
		}
1441
		$db->sql_freeresult($result);
1442
	
1443
		$index = array();
1444
		$sql = "EXEC sp_statistics '$table_name'";
1445
		$result = $db->sql_query($sql);
1446
		while ($row = $db->sql_fetchrow($result))
1447
		{
1448
			if ($row['TYPE'] == 3)
1449
			{
1450
				$index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
1451
			}
1452
		}
1453
		$db->sql_freeresult($result);
1454
	
1455
		foreach ($index as $index_name => $column_name)
1456
		{
1457
			$index[$index_name] = implode(', ', $column_name);
1458
		}
1459
	
1460
		foreach ($index as $index_name => $columns)
1461
		{
1462
			$sql_data .= "\nCREATE  INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
1463
		}
1464
		$this->flush($sql_data);
1465
	}
1466
1467
	function write_data($table_name)
1468
	{
1469
		global $db;
1470
1471
		if ($db->sql_layer === 'mssql')
1472
		{
1473
			$this->write_data_mssql($table_name);
1474
		}
1475
		else
1476
		{
1477
			$this->write_data_odbc($table_name);
1478
		}
1479
	}
1480
1481
	function write_data_mssql($table_name)
1482
	{
1483
		global $db;
1484
		$ary_type = $ary_name = array();
1485
		$ident_set = false;
1486
		$sql_data = '';
1487
		
1488
		// Grab all of the data from current table.
1489
		$sql = "SELECT *
1490
			FROM $table_name";
1491
		$result = $db->sql_query($sql);
1492
1493
		$retrieved_data = mssql_num_rows($result);
1494
1495
		$i_num_fields = mssql_num_fields($result);
1496
1497
		for ($i = 0; $i < $i_num_fields; $i++)
1498
		{
1499
			$ary_type[$i] = mssql_field_type($result, $i);
1500
			$ary_name[$i] = mssql_field_name($result, $i);
1501
		}
1502
1503
		if ($retrieved_data)
1504
		{
1505
			$sql = "SELECT 1 as has_identity
1506
				FROM INFORMATION_SCHEMA.COLUMNS
1507
				WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1508
			$result2 = $db->sql_query($sql);
1509
			$row2 = $db->sql_fetchrow($result2);
1510
			if (!empty($row2['has_identity']))
1511
			{
1512
				$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1513
				$ident_set = true;
1514
			}
1515
			$db->sql_freeresult($result2);
1516
		}
1517
1518
		while ($row = $db->sql_fetchrow($result))
1519
		{
1520
			$schema_vals = $schema_fields = array();
1521
1522
			// Build the SQL statement to recreate the data.
1523
			for ($i = 0; $i < $i_num_fields; $i++)
1524
			{
1525
				$str_val = $row[$ary_name[$i]];
1526
1527
				if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1528
				{
1529
					$str_quote = '';
1530
					$str_empty = "''";
1531
					$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1532
				}
1533
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1534
				{
1535
					if (empty($str_val))
1536
					{
1537
						$str_quote = '';
1538
					}
1539
					else
1540
					{
1541
						$str_quote = "'";
1542
					}
1543
				}
1544
				else
1545
				{
1546
					$str_quote = '';
1547
					$str_empty = 'NULL';
1548
				}
1549
1550
				if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
1551
				{
1552
					$str_val = $str_empty;
1553
				}
1554
1555
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1556
				$schema_fields[$i] = $ary_name[$i];
1557
			}
1558
1559
			// Take the ordered fields and their associated data and build it
1560
			// into a valid sql statement to recreate that field in the data.
1561
			$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1562
1563
			$this->flush($sql_data);
1564
			$sql_data = '';
1565
		}
1566
		$db->sql_freeresult($result);
1567
1568
		if ($retrieved_data && $ident_set)
1569
		{
1570
			$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1571
		}
1572
		$this->flush($sql_data);
1573
	}
1574
1575
	function write_data_odbc($table_name)
1576
	{
1577
		global $db;
1578
		$ary_type = $ary_name = array();
1579
		$ident_set = false;
1580
		$sql_data = '';
1581
		
1582
		// Grab all of the data from current table.
1583
		$sql = "SELECT *
1584
			FROM $table_name";
1585
		$result = $db->sql_query($sql);
1586
1587
		$retrieved_data = odbc_num_rows($result);
1588
1589
		if ($retrieved_data)
1590
		{
1591
			$sql = "SELECT 1 as has_identity
1592
				FROM INFORMATION_SCHEMA.COLUMNS
1593
				WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1594
			$result2 = $db->sql_query($sql);
1595
			$row2 = $db->sql_fetchrow($result2);
1596
			if (!empty($row2['has_identity']))
1597
			{
1598
				$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1599
				$ident_set = true;
1600
			}
1601
			$db->sql_freeresult($result2);
1602
		}
1603
1604
		$i_num_fields = odbc_num_fields($result);
1605
1606
		for ($i = 0; $i < $i_num_fields; $i++)
1607
		{
1608
			$ary_type[$i] = odbc_field_type($result, $i + 1);
1609
			$ary_name[$i] = odbc_field_name($result, $i + 1);
1610
		}
1611
1612
		while ($row = $db->sql_fetchrow($result))
1613
		{
1614
			$schema_vals = $schema_fields = array();
1615
1616
			// Build the SQL statement to recreate the data.
1617
			for ($i = 0; $i < $i_num_fields; $i++)
1618
			{
1619
				$str_val = $row[$ary_name[$i]];
1620
1621
				if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1622
				{
1623
					$str_quote = '';
1624
					$str_empty = "''";
1625
					$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1626
				}
1627
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1628
				{
1629
					if (empty($str_val))
1630
					{
1631
						$str_quote = '';
1632
					}
1633
					else
1634
					{
1635
						$str_quote = "'";
1636
					}
1637
				}
1638
				else
1639
				{
1640
					$str_quote = '';
1641
					$str_empty = 'NULL';
1642
				}
1643
1644
				if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
1645
				{
1646
					$str_val = $str_empty;
1647
				}
1648
1649
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1650
				$schema_fields[$i] = $ary_name[$i];
1651
			}
1652
1653
			// Take the ordered fields and their associated data and build it
1654
			// into a valid sql statement to recreate that field in the data.
1655
			$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1656
1657
			$this->flush($sql_data);
1658
1659
			$sql_data = '';
1660
1661
		}
1662
		$db->sql_freeresult($result);
1663
1664
		if ($retrieved_data && $ident_set)
1665
		{
1666
			$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1667
		}
1668
		$this->flush($sql_data);
1669
	}
1670
1671
}
1672
1673
/**
1674
* @package acp
1675
*/
1676
class oracle_extractor extends base_extractor
1677
{
1678
	function write_table($table_name)
1679
	{
1680
		global $db;
1681
		$sql_data = '-- Table: ' . $table_name . "\n";
1682
		$sql_data .= "DROP TABLE $table_name;\n";
1683
		$sql_data .= '\\' . "\n";
1684
		$sql_data .= "\nCREATE TABLE $table_name (\n";
1685
1686
		$sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
1687
			FROM ALL_TAB_COLS
1688
			WHERE table_name = '{$table_name}'";
1689
		$result = $db->sql_query($sql);
1690
1691
		$rows = array();
1692
		while ($row = $db->sql_fetchrow($result))
1693
		{
1694
			$line = '  "' . $row['column_name'] . '" ' . $row['data_type'];
1695
1696
			if ($row['data_type'] !== 'CLOB')
1697
			{
1698
				if ($row['data_type'] !== 'VARCHAR2')
1699
				{
1700
					$line .= '(' . $row['data_precision'] . ')';
1701
				}
1702
				else
1703
				{
1704
					$line .= '(' . $row['data_length'] . ')';
1705
				}
1706
			}
1707
1708
			if (!empty($row['data_default']))
1709
			{
1710
				$line .= ' DEFAULT ' . $row['data_default'];
1711
			}
1712
1713
			if ($row['nullable'] == 'N')
1714
			{
1715
				$line .= ' NOT NULL';
1716
			}
1717
			$rows[] = $line;
1718
		}
1719
		$db->sql_freeresult($result);
1720
1721
		$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1722
			FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1723
			WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1724
				AND B.CONSTRAINT_TYPE = 'P'
1725
				AND A.TABLE_NAME = '{$table_name}'";
1726
		$result = $db->sql_query($sql);
1727
1728
		while ($row = $db->sql_fetchrow($result))
1729
		{
1730
			$rows[] = "  CONSTRAINT {$row['constraint_name']} PRIMARY KEY ({$row['column_name']})";
1731
		}
1732
		$db->sql_freeresult($result);
1733
1734
		$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1735
			FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1736
			WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1737
				AND B.CONSTRAINT_TYPE = 'U'
1738
				AND A.TABLE_NAME = '{$table_name}'";
1739
		$result = $db->sql_query($sql);
1740
1741
		while ($row = $db->sql_fetchrow($result))
1742
		{
1743
			$rows[] = "  CONSTRAINT {$row['constraint_name']} UNIQUE ({$row['column_name']})";
1744
		}
1745
		$db->sql_freeresult($result);
1746
1747
		$sql_data .= implode(",\n", $rows);
1748
		$sql_data .= "\n)\n\\";
1749
1750
		$sql = "SELECT A.REFERENCED_NAME
1751
			FROM USER_DEPENDENCIES A, USER_TRIGGERS B
1752
			WHERE A.REFERENCED_TYPE = 'SEQUENCE'
1753
				AND A.NAME = B.TRIGGER_NAME
1754
				AND B. TABLE_NAME = '{$table_name}'";
1755
		$result = $db->sql_query($sql);
1756
		while ($row = $db->sql_fetchrow($result))
1757
		{
1758
			$sql_data .= "\nCREATE SEQUENCE {$row['referenced_name']}\\\n";
1759
		}
1760
		$db->sql_freeresult($result);
1761
1762
		$sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
1763
			FROM USER_TRIGGERS
1764
			WHERE TABLE_NAME = '{$table_name}'";
1765
		$result = $db->sql_query($sql);
1766
		while ($row = $db->sql_fetchrow($result))
1767
		{
1768
			$sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\\";
1769
		}
1770
		$db->sql_freeresult($result);
1771
1772
		$sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
1773
			FROM USER_INDEXES A, USER_IND_COLUMNS B
1774
			WHERE A.UNIQUENESS = 'NONUNIQUE'
1775
				AND A.INDEX_NAME = B.INDEX_NAME
1776
				AND B.TABLE_NAME = '{$table_name}'";
1777
		$result = $db->sql_query($sql);
1778
1779
		$index = array();
1780
1781
		while ($row = $db->sql_fetchrow($result))
1782
		{
1783
			$index[$row['index_name']][] = $row['column_name'];
1784
		}
1785
1786
		foreach ($index as $index_name => $column_names)
1787
		{
1788
			$sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n\\";
1789
		}
1790
		$db->sql_freeresult($result);
1791
		$this->flush($sql_data);
1792
	}
1793
1794
	function write_data($table_name)
1795
	{
1796
		global $db;
1797
		$ary_type = $ary_name = array();
1798
		
1799
		// Grab all of the data from current table.
1800
		$sql = "SELECT *
1801
			FROM $table_name";
1802
		$result = $db->sql_query($sql);
1803
1804
		$i_num_fields = ocinumcols($result);
1805
1806
		for ($i = 0; $i < $i_num_fields; $i++)
1807
		{
1808
			$ary_type[$i] = ocicolumntype($result, $i + 1);
1809
			$ary_name[$i] = ocicolumnname($result, $i + 1);
1810
		}
1811
1812
		$sql_data = '';
1813
1814
		while ($row = $db->sql_fetchrow($result))
1815
		{
1816
			$schema_vals = $schema_fields = array();
1817
1818
			// Build the SQL statement to recreate the data.
1819
			for ($i = 0; $i < $i_num_fields; $i++)
1820
			{
1821
				$str_val = $row[$ary_name[$i]];
1822
1823
				if (preg_match('#char|text|bool|raw#i', $ary_type[$i]))
1824
				{
1825
					$str_quote = '';
1826
					$str_empty = "''";
1827
					$str_val = sanitize_data_oracle($str_val);
1828
				}
1829
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1830
				{
1831
					if (empty($str_val))
1832
					{
1833
						$str_quote = '';
1834
					}
1835
					else
1836
					{
1837
						$str_quote = "'";
1838
					}
1839
				}
1840
				else
1841
				{
1842
					$str_quote = '';
1843
					$str_empty = 'NULL';
1844
				}
1845
1846
				if (empty($str_val) && $str_val !== '0')
1847
				{
1848
					$str_val = $str_empty;
1849
				}
1850
1851
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1852
				$schema_fields[$i] = '"' . $ary_name[$i] . "'";
1853
			}
1854
1855
			// Take the ordered fields and their associated data and build it
1856
			// into a valid sql statement to recreate that field in the data.
1857
			$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1858
1859
			$this->flush($sql_data);
1860
		}
1861
		$db->sql_freeresult($result);
1862
	}
1863
1864
	function write_start($prefix)
1865
	{
1866
		$sql_data = "--\n";
1867
		$sql_data .= "-- phpBB Backup Script\n";
1868
		$sql_data .= "-- Dump of tables for $prefix\n";
1869
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1870
		$sql_data .= "--\n";
1871
		$this->flush($sql_data);
1872
	}
1873
}
1874
1875
/**
1876
* @package acp
1877
*/
1878
class firebird_extractor extends base_extractor
1879
{
1880
	function write_start($prefix)
1881
	{
1882
		$sql_data = "--\n";
1883
		$sql_data .= "-- phpBB Backup Script\n";
1884
		$sql_data .= "-- Dump of tables for $prefix\n";
1885
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1886
		$sql_data .= "--\n";
1887
		$this->flush($sql_data);
1888
	}
1889
1890
	function write_data($table_name)
1891
	{
1892
		global $db;
1893
		$ary_type = $ary_name = array();
1894
		
1895
		// Grab all of the data from current table.
1896
		$sql = "SELECT *
1897
			FROM $table_name";
1898
		$result = $db->sql_query($sql);
1899
1900
		$i_num_fields = ibase_num_fields($result);
1901
1902
		for ($i = 0; $i < $i_num_fields; $i++)
1903
		{
1904
			$info = ibase_field_info($result, $i);
1905
			$ary_type[$i] = $info['type'];
1906
			$ary_name[$i] = $info['name'];
1907
		}
1908
1909
		while ($row = $db->sql_fetchrow($result))
1910
		{
1911
			$schema_vals = $schema_fields = array();
1912
1913
			// Build the SQL statement to recreate the data.
1914
			for ($i = 0; $i < $i_num_fields; $i++)
1915
			{
1916
				$str_val = $row[strtolower($ary_name[$i])];
1917
1918
				if (preg_match('#char|text|bool|varbinary|blob#i', $ary_type[$i]))
1919
				{
1920
					$str_quote = '';
1921
					$str_empty = "''";
1922
					$str_val = sanitize_data_generic(str_replace("'", "''", $str_val));
1923
				}
1924
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1925
				{
1926
					if (empty($str_val))
1927
					{
1928
						$str_quote = '';
1929
					}
1930
					else
1931
					{
1932
						$str_quote = "'";
1933
					}
1934
				}
1935
				else
1936
				{
1937
					$str_quote = '';
1938
					$str_empty = 'NULL';
1939
				}
1940
1941
				if (empty($str_val) && $str_val !== '0')
1942
				{
1943
					$str_val = $str_empty;
1944
				}
1945
1946
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1947
				$schema_fields[$i] = '"' . $ary_name[$i] . '"';
1948
			}
1949
1950
			// Take the ordered fields and their associated data and build it
1951
			// into a valid sql statement to recreate that field in the data.
1952
			$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1953
1954
			$this->flush($sql_data);
1955
		}
1956
		$db->sql_freeresult($result);
1957
	}
1958
1959
	function write_table($table_name)
1960
	{
1961
		global $db;
1962
1963
		$sql_data = '-- Table: ' . $table_name . "\n";
1964
		$sql_data .= "DROP TABLE $table_name;\n";
1965
1966
		$data_types = array(7 => 'SMALLINT', 8 => 'INTEGER', 10 => 'FLOAT', 12 => 'DATE', 13 => 'TIME', 14 => 'CHARACTER', 27 => 'DOUBLE PRECISION', 35 => 'TIMESTAMP', 37 => 'VARCHAR', 40 => 'CSTRING', 261 => 'BLOB', 701 => 'DECIMAL', 702 => 'NUMERIC');
1967
1968
		$sql_data .= "\nCREATE TABLE $table_name (\n";
1969
1970
		$sql = 'SELECT DISTINCT R.RDB$FIELD_NAME as FNAME, R.RDB$NULL_FLAG as NFLAG, R.RDB$DEFAULT_SOURCE as DSOURCE, F.RDB$FIELD_TYPE as FTYPE, F.RDB$FIELD_SUB_TYPE as STYPE, F.RDB$FIELD_LENGTH as FLEN
1971
			FROM RDB$RELATION_FIELDS R
1972
			JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME
1973
			LEFT JOIN RDB$FIELD_DIMENSIONS D ON R.RDB$FIELD_SOURCE = D.RDB$FIELD_NAME
1974
			WHERE F.RDB$SYSTEM_FLAG = 0
1975
				AND R.RDB$RELATION_NAME = \''. $table_name . '\'
1976
			ORDER BY R.RDB$FIELD_POSITION';
1977
		$result = $db->sql_query($sql);
1978
1979
		$rows = array();
1980
		while ($row = $db->sql_fetchrow($result))
1981
		{
1982
			$line = "\t" . '"' . $row['fname'] . '" ' . $data_types[$row['ftype']];
1983
1984
			if ($row['ftype'] == 261 && $row['stype'] == 1)
1985
			{
1986
				$line .= ' SUB_TYPE TEXT';
1987
			}
1988
1989
			if ($row['ftype'] == 37 || $row['ftype'] == 14)
1990
			{
1991
				$line .= ' (' . $row['flen'] . ')';
1992
			}
1993
1994
			if (!empty($row['dsource']))
1995
			{
1996
				$line .= ' ' . $row['dsource'];
1997
			}
1998
1999
			if (!empty($row['nflag']))
2000
			{
2001
				$line .= ' NOT NULL';
2002
			}
2003
			$rows[] = $line;
2004
		}
2005
		$db->sql_freeresult($result);
2006
2007
		$sql_data .= implode(",\n", $rows);
2008
		$sql_data .= "\n);\n";
2009
		$keys = array();
2010
2011
		$sql = 'SELECT I.RDB$FIELD_NAME as NAME
2012
			FROM RDB$RELATION_CONSTRAINTS RC, RDB$INDEX_SEGMENTS I, RDB$INDICES IDX
2013
			WHERE (I.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2014
				AND (IDX.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2015
				AND (RC.RDB$RELATION_NAME = \''. $table_name . '\')
2016
			ORDER BY I.RDB$FIELD_POSITION';
2017
		$result = $db->sql_query($sql);
2018
2019
		while ($row = $db->sql_fetchrow($result))
2020
		{
2021
			$keys[] = $row['name'];
2022
		}
2023
2024
		if (sizeof($keys))
2025
		{
2026
			$sql_data .= "\nALTER TABLE $table_name ADD PRIMARY KEY (" . implode(', ', $keys) . ');';
2027
		}
2028
2029
		$db->sql_freeresult($result);
2030
2031
		$sql = 'SELECT I.RDB$INDEX_NAME as INAME, I.RDB$UNIQUE_FLAG as UFLAG, S.RDB$FIELD_NAME as FNAME
2032
			FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON S.RDB$INDEX_NAME=I.RDB$INDEX_NAME
2033
			WHERE (I.RDB$SYSTEM_FLAG IS NULL  OR  I.RDB$SYSTEM_FLAG=0)
2034
				AND I.RDB$FOREIGN_KEY IS NULL
2035
				AND I.RDB$RELATION_NAME = \''. $table_name . '\'
2036
				AND I.RDB$INDEX_NAME NOT STARTING WITH \'RDB$\'
2037
			ORDER BY S.RDB$FIELD_POSITION';
2038
		$result = $db->sql_query($sql);
2039
2040
		$index = array();
2041
		while ($row = $db->sql_fetchrow($result))
2042
		{
2043
			$index[$row['iname']]['unique'] = !empty($row['uflag']);
2044
			$index[$row['iname']]['values'][] = $row['fname'];
2045
		}
2046
2047
		foreach ($index as $index_name => $data)
2048
		{
2049
			$sql_data .= "\nCREATE ";
2050
			if ($data['unique'])
2051
			{
2052
				$sql_data .= 'UNIQUE ';
2053
			}
2054
			$sql_data .= "INDEX $index_name ON $table_name(" . implode(', ', $data['values']) . ");";
2055
		}
2056
		$sql_data .= "\n";
2057
2058
		$db->sql_freeresult($result);
2059
2060
		$sql = 'SELECT D1.RDB$DEPENDENT_NAME as DNAME, D1.RDB$FIELD_NAME as FNAME, D1.RDB$DEPENDENT_TYPE, R1.RDB$RELATION_NAME
2061
			FROM RDB$DEPENDENCIES D1
2062
			LEFT JOIN RDB$RELATIONS R1 ON ((D1.RDB$DEPENDENT_NAME = R1.RDB$RELATION_NAME) AND (NOT (R1.RDB$VIEW_BLR IS NULL)))
2063
			WHERE (D1.RDB$DEPENDED_ON_TYPE = 0)
2064
				AND (D1.RDB$DEPENDENT_TYPE <> 3)
2065
				AND (D1.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2066
			UNION SELECT DISTINCT F2.RDB$RELATION_NAME, D2.RDB$FIELD_NAME, D2.RDB$DEPENDENT_TYPE, R2.RDB$RELATION_NAME FROM RDB$DEPENDENCIES D2, RDB$RELATION_FIELDS F2
2067
			LEFT JOIN RDB$RELATIONS R2 ON ((F2.RDB$RELATION_NAME = R2.RDB$RELATION_NAME) AND (NOT (R2.RDB$VIEW_BLR IS NULL)))
2068
			WHERE (D2.RDB$DEPENDENT_TYPE = 3)
2069
				AND (D2.RDB$DEPENDENT_NAME = F2.RDB$FIELD_SOURCE)
2070
				AND (D2.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2071
			ORDER BY 1, 2';
2072
		$result = $db->sql_query($sql);
2073
		while ($row = $db->sql_fetchrow($result))
2074
		{
2075
			$sql = 'SELECT T1.RDB$DEPENDED_ON_NAME as GEN, T1.RDB$FIELD_NAME, T1.RDB$DEPENDED_ON_TYPE
2076
				FROM RDB$DEPENDENCIES T1
2077
				WHERE (T1.RDB$DEPENDENT_NAME = \'' . $row['dname'] . '\')
2078
					AND (T1.RDB$DEPENDENT_TYPE = 2 AND T1.RDB$DEPENDED_ON_TYPE = 14)
2079
				UNION ALL SELECT DISTINCT D.RDB$DEPENDED_ON_NAME, D.RDB$FIELD_NAME, D.RDB$DEPENDED_ON_TYPE
2080
				FROM RDB$DEPENDENCIES D, RDB$RELATION_FIELDS F
2081
				WHERE (D.RDB$DEPENDENT_TYPE = 3)
2082
					AND (D.RDB$DEPENDENT_NAME = F.RDB$FIELD_SOURCE)
2083
					AND (F.RDB$RELATION_NAME = \'' . $row['dname'] . '\')
2084
				ORDER BY 1,2';
2085
			$result2 = $db->sql_query($sql);
2086
			$row2 = $db->sql_fetchrow($result2);
2087
			$db->sql_freeresult($result2);
2088
			$gen_name = $row2['gen'];
2089
2090
			$sql_data .= "\nDROP GENERATOR " . $gen_name . ";";
2091
			$sql_data .= "\nSET TERM ^ ;";
2092
			$sql_data .= "\nCREATE GENERATOR " . $gen_name . "^";
2093
			$sql_data .= "\nSET GENERATOR  " . $gen_name . " TO 0^\n";
2094
			$sql_data .= "\nCREATE TRIGGER {$row['dname']} FOR $table_name";
2095
			$sql_data .= "\nBEFORE INSERT\nAS\nBEGIN";
2096
			$sql_data .= "\n  NEW.{$row['fname']} = GEN_ID(" . $gen_name . ", 1);";
2097
			$sql_data .= "\nEND^\n";
2098
			$sql_data .= "\nSET TERM ; ^\n";
2099
		}
2100
2101
		$this->flush($sql_data);
2102
2103
		$db->sql_freeresult($result);
2104
	}
2105
}
2106
2107
// get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P)
2108
function get_usable_memory()
2109
{
2110
	$val = trim(@ini_get('memory_limit'));
2111
2112
	if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
2113
	{
2114
		$memory_limit = (int) $regs[1];
2115
		switch ($regs[2])
2116
		{
2117
2118
			case 'k':
2119
			case 'K':
2120
				$memory_limit *= 1024;
2121
			break;
2122
2123
			case 'm':
2124
			case 'M':
2125
				$memory_limit *= 1048576;
2126
			break;
2127
2128
			case 'g':
2129
			case 'G':
2130
				$memory_limit *= 1073741824;
2131
			break;
2132
		}
2133
2134
		// how much memory PHP requires at the start of export (it is really a little less)
2135
		if ($memory_limit > 6100000)
2136
		{
2137
			$memory_limit -= 6100000;
2138
		}
2139
2140
		// allow us to consume half of the total memory available
2141
		$memory_limit /= 2;
2142
	}
2143
	else
2144
	{
2145
		// set the buffer to 1M if we have no clue how much memory PHP will give us :P
2146
		$memory_limit = 1048576;
2147
	}
2148
2149
	return $memory_limit;
2150
}
2151
2152
function sanitize_data_mssql($text)
2153
{
2154
	$data = preg_split('/[\n\t\r\b\f]/', $text);
2155
	preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2156
2157
	$val = array();
2158
2159
	foreach ($data as $value)
2160
	{
2161
		if (strlen($value))
2162
		{
2163
			$val[] = "'" . $value . "'";
2164
		}
2165
		if (sizeof($matches[0]))
2166
		{
2167
			$val[] = 'char(' . ord(array_shift($matches[0])) . ')';
2168
		}
2169
	}
2170
2171
	return implode('+', $val);
2172
}
2173
2174
function sanitize_data_oracle($text)
2175
{
2176
	$data = preg_split('/[\0\n\t\r\b\f\'"\\\]/', $text);
2177
	preg_match_all('/[\0\n\t\r\b\f\'"\\\]/', $text, $matches);
2178
2179
	$val = array();
2180
2181
	foreach ($data as $value)
2182
	{
2183
		if (strlen($value))
2184
		{
2185
			$val[] = "'" . $value . "'";
2186
		}
2187
		if (sizeof($matches[0]))
2188
		{
2189
			$val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
2190
		}
2191
	}
2192
2193
	return implode('||', $val);
2194
}
2195
2196
function sanitize_data_generic($text)
2197
{
2198
	$data = preg_split('/[\n\t\r\b\f]/', $text);
2199
	preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2200
2201
	$val = array();
2202
2203
	foreach ($data as $value)
2204
	{
2205
		if (strlen($value))
2206
		{
2207
			$val[] = "'" . $value . "'";
2208
		}
2209
		if (sizeof($matches[0]))
2210
		{
2211
			$val[] = "'" . array_shift($matches[0]) . "'";
2212
		}
2213
	}
2214
2215
	return implode('||', $val);
2216
}
2217
2218
// modified from PHP.net
2219
function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2220
{
2221
	$record = '';
2222
	$delim_len = strlen($delim);
2223
	
2224
	while (!$eof($fp))
2225
	{
2226
		$pos = strpos($record, $delim);
2227
		if ($pos === false)
2228
		{
2229
			$record .= $read($fp, $buffer);
2230
			if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
2231
			{
2232
				$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
2233
				return substr($record, 0, $pos);
2234
			}
2235
		}
2236
		else
2237
		{
2238
			$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
2239
			return substr($record, 0, $pos);
2240
		}
2241
	}
2242
2243
	return false;
2244
}
2245
2246
function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2247
{
2248
	static $array = array();
2249
	static $record = '';
2250
2251
	if (!sizeof($array))
2252
	{
2253
		while (!$eof($fp))
2254
		{
2255
			if (strpos($record, $delim) !== false)
2256
			{
2257
				$array = explode($delim, $record);
2258
				$record = array_pop($array);
2259
				break;
2260
			}
2261
			else
2262
			{
2263
				$record .= $read($fp, $buffer);
2264
			}
2265
		}
2266
		if ($eof($fp) && strpos($record, $delim) !== false)
2267
		{
2268
			$array = explode($delim, $record);
2269
			$record = array_pop($array);
2270
		}
2271
	}
2272
2273
	if (sizeof($array))
2274
	{
2275
		return array_shift($array);
2276
	}
2277
2278
	return false;
2279
}
2280
2281
?>