<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/

/**
* This file creates new schema files for every database.
* The filenames will be prefixed with an underscore to not overwrite the current schema files.
*
* If you overwrite the original schema files please make sure you save the file with UNIX linefeeds.
*/

$schema_path = dirname(__FILE__) . '/../install/schemas/';
$supported_dbms = array(
	'firebird',
	'mssql',
	'mysql_40',
	'mysql_41',
	'oracle',
	'postgres',
	'sqlite',
);
$table_prefix = 'phpbb_';

if (!is_writable($schema_path))
{
	die('Schema path not writable');
}

define('IN_PHPBB', true);
$phpbb_root_path = dirname(__FILE__) . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);

include($phpbb_root_path . 'includes/constants.' . $phpEx);
require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx);
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
$phpbb_class_loader->register();

class phpbb_extension_empty_manager extends \phpbb\extension\manager
{
	public function __construct()
	{
		$this->extensions = array();
	}
}

$finder = new \phpbb\extension\finder(new \phpbb_extension_empty_manager(), new \phpbb\filesystem(), $phpbb_root_path);
$classes = $finder->core_path('phpbb/')
	->directory('db/migration/data')
	->get_classes();

$db = new \phpbb\db\driver\sqlite();
$schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, new \phpbb\db\tools($db, true), $phpbb_root_path, $phpEx, $table_prefix);
$schema_data = $schema_generator->get_schema();
$dbms_type_map = phpbb\db\tools::get_dbms_type_map();

$fp = fopen($schema_path . 'schema.json', 'wb');
fwrite($fp, json_encode($schema_data, JSON_PRETTY_PRINT));
fclose($fp);

foreach ($supported_dbms as $dbms)
{
	$fp = fopen($schema_path . $dbms . '_schema.sql', 'wb');

	// Write Header
	switch ($dbms)
	{
		case 'mysql_40':
		case 'mysql_41':
		case 'firebird':
		case 'sqlite':
		case 'sqlite3':
			fwrite($fp, "# DO NOT EDIT THIS FILE, IT IS GENERATED\n");
			fwrite($fp, "#\n");
			fwrite($fp, "# To change the contents of this file, edit\n");
			fwrite($fp, "# phpBB/develop/create_schema_files.php and\n");
			fwrite($fp, "# run it.\n");
		break;

		case 'mssql':
		case 'oracle':
		case 'postgres':
			fwrite($fp, "/*\n");
			fwrite($fp, " * DO NOT EDIT THIS FILE, IT IS GENERATED\n");
			fwrite($fp, " *\n");
			fwrite($fp, " * To change the contents of this file, edit\n");
			fwrite($fp, " * phpBB/develop/create_schema_files.php and\n");
			fwrite($fp, " * run it.\n");
			fwrite($fp, " */\n\n");
		break;
	}

	$line = '';
	switch ($dbms)
	{
		case 'oracle':
			$line .= custom_data('oracle') . "\n";
		break;

		case 'postgres':
			$line .= "BEGIN;\n\n";
			$line .= custom_data('postgres') . "\n";
			$line .= "COMMIT;\n\n";
		break;
	}

	fwrite($fp, $line);
	fclose($fp);
}

/**
* Data put into the header for various dbms
*/
function custom_data($dbms)
{
	switch ($dbms)
	{
		case 'oracle':
			return <<<EOF
/*
  This first section is optional, however its probably the best method
  of running phpBB on Oracle. If you already have a tablespace and user created
  for phpBB you can leave this section commented out!

  The first set of statements create a phpBB tablespace and a phpBB user,
  make sure you change the password of the phpBB user before you run this script!!
*/

/*
CREATE TABLESPACE "PHPBB"
	LOGGING
	DATAFILE 'E:\ORACLE\ORADATA\LOCAL\PHPBB.ora'
	SIZE 10M
	AUTOEXTEND ON NEXT 10M
	MAXSIZE 100M;

CREATE USER "PHPBB"
	PROFILE "DEFAULT"
	IDENTIFIED BY "phpbb_password"
	DEFAULT TABLESPACE "PHPBB"
	QUOTA UNLIMITED ON "PHPBB"
	ACCOUNT UNLOCK;

GRANT ANALYZE ANY TO "PHPBB";
GRANT CREATE SEQUENCE TO "PHPBB";
GRANT CREATE SESSION TO "PHPBB";
GRANT CREATE TABLE TO "PHPBB";
GRANT CREATE TRIGGER TO "PHPBB";
GRANT CREATE VIEW TO "PHPBB";
GRANT "CONNECT" TO "PHPBB";

COMMIT;
DISCONNECT;

CONNECT phpbb/phpbb_password;
*/
EOF;

		break;

		case 'postgres':
			return <<<EOF
/*
	Domain definition
*/
CREATE DOMAIN varchar_ci AS varchar(255) NOT NULL DEFAULT ''::character varying;

/*
	Operation Functions
*/
CREATE FUNCTION _varchar_ci_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) = LOWER($2)' LANGUAGE SQL STRICT;
CREATE FUNCTION _varchar_ci_not_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) != LOWER($2)' LANGUAGE SQL STRICT;
CREATE FUNCTION _varchar_ci_less_than(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) < LOWER($2)' LANGUAGE SQL STRICT;
CREATE FUNCTION _varchar_ci_less_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) <= LOWER($2)' LANGUAGE SQL STRICT;
CREATE FUNCTION _varchar_ci_greater_than(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) > LOWER($2)' LANGUAGE SQL STRICT;
CREATE FUNCTION _varchar_ci_greater_equals(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) >= LOWER($2)' LANGUAGE SQL STRICT;

/*
	Operators
*/
CREATE OPERATOR <(
  PROCEDURE = _varchar_ci_less_than,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = >,
  NEGATOR = >=,
  RESTRICT = scalarltsel,
  JOIN = scalarltjoinsel);

CREATE OPERATOR <=(
  PROCEDURE = _varchar_ci_less_equal,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = >=,
  NEGATOR = >,
  RESTRICT = scalarltsel,
  JOIN = scalarltjoinsel);

CREATE OPERATOR >(
  PROCEDURE = _varchar_ci_greater_than,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = <,
  NEGATOR = <=,
  RESTRICT = scalargtsel,
  JOIN = scalargtjoinsel);

CREATE OPERATOR >=(
  PROCEDURE = _varchar_ci_greater_equals,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = <=,
  NEGATOR = <,
  RESTRICT = scalargtsel,
  JOIN = scalargtjoinsel);

CREATE OPERATOR <>(
  PROCEDURE = _varchar_ci_not_equal,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = <>,
  NEGATOR = =,
  RESTRICT = neqsel,
  JOIN = neqjoinsel);

CREATE OPERATOR =(
  PROCEDURE = _varchar_ci_equal,
  LEFTARG = varchar_ci,
  RIGHTARG = varchar_ci,
  COMMUTATOR = =,
  NEGATOR = <>,
  RESTRICT = eqsel,
  JOIN = eqjoinsel,
  HASHES,
  MERGES,
  SORT1= <);

EOF;
		break;
	}

	return '';
}

echo 'done';
