<commit_before><?php

/**
 * This file has all the main functions in it that relate to the database.
 *
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2014 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 Alpha 1
 */

if (!defined('SMF'))
	die('No direct access...');

/**
 *  Maps the implementations in this file (smf_db_function_name)
 *  to the $smcFunc['db_function_name'] variable.
 *
 * @param string $db_server
 * @param string $db_name
 * @param string $db_user
 * @param string $db_passwd
 * @param string $db_prefix
 * @param array $db_options
 */
function smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_options = array())
{
	global $smcFunc, $mysql_set_mode, $db_in_transact, $sqlite_error;

	// Map some database specific functions, only do this once.
	// SQLite3 does not have any procedural functions, so we need to map them all...
	if (!isset($smcFunc['db_fetch_assoc']) || $smcFunc['db_fetch_assoc'] != 'smf_db_fetch_array')
		$smcFunc += array(
			'db_query' => 'smf_db_query',
			'db_quote' => 'smf_db_quote',
			'db_fetch_assoc' => 'smf_db_fetch_array',
			'db_fetch_row' => 'smf_db_fetch_row',
			'db_free_result' => 'smf_db_free_result',
			'db_insert' => 'smf_db_insert',
			'db_insert_id' => 'smf_db_insert_id',
			'db_num_rows' => 'smf_db_num_rows',
			'db_data_seek' => 'smf_db_seek',
			'db_num_fields' => 'smf_db_num_fields',
			'db_escape_string' => 'smf_db_escape_string',
			'db_unescape_string' => 'smf_db_unescape_string',
			'db_server_info' => 'smf_db_libversion',
			'db_affected_rows' => 'smf_db_affected_rows',
			'db_transaction' => 'smf_db_transaction',
			'db_error' => 'smf_db_last_error',
			'db_select_db' => '',
			'db_title' => 'SQLite3',
			'db_sybase' => true,
			'db_case_sensitive' => true,
			'db_escape_wildcard_string' => 'smf_db_escape_wildcard_string',
		);

	if (substr($db_name, -3) != '.db')
		$db_name .= '.db';

	// SQLite3 doesn't support persistent connections...
	$connection = new SQLite3($db_name);

	// Something's wrong, show an error if its fatal (which we assume it is)
	if (!$connection)
	{
		if (!empty($db_options['non_fatal']))
			return null;
		else
			display_db_error();
	}
	$db_in_transact = false;

	// This is frankly stupid - stop SQLite returning alias names!
	@$connection->exec('PRAGMA short_column_names = 1');

	// Make some user defined functions!
	smf_db_define_udfs($connection);

	return $connection;
}

/**
 * Extend the database functionality. It calls the respective file's init
 * to add the implementations in that file to $smcFunc array.
 *
 * @param string $type indicated which additional file to load. ('extra', 'packages')
 */
function db_extend($type = 'extra')
{
	global $sourcedir, $db_type;

	require_once($sourcedir . '/Db' . strtoupper($type[0]) . substr($type, 1) . '-' . $db_type . '.php');
	$initFunc = 'db_' . $type . '_init';
	$initFunc();
}

/**
 * Verify that we have a valid connection
 * 
 * @param resource $connection
 * Thanks to tinoest for this idea
 */
function smf_db_check_connection($connection)
{
	global $db_name;

 	if (!is_object($connection) || is_null($connection))
 	{
 		if (substr($db_name, -3) != '.db')
 			$db_name .= '.db';

		$connection = new Sqlite3($db_name);

		smf_db_define_udfs($connection);
	}

	return $connection;
}

/**
 * Define user-defined functions for SQLite3
 * @param resource $connection
 */
function smf_db_define_udfs(&$connection)
{
	$connection->createFunction('unix_timestamp', 'smf_udf_unix_timestamp', 0);
	$connection->createFunction('inet_aton', 'smf_udf_inet_aton', 1);
	$connection->createFunction('inet_ntoa', 'smf_udf_inet_ntoa', 1);
	$connection->createFunction('find_in_set', 'smf_udf_find_in_set', 2);
	$connection->createFunction('year', 'smf_udf_year', 1);
	$connection->createFunction('month', 'smf_udf_month', 1);
	$connection->createFunction('dayofmonth', 'smf_udf_dayofmonth', 1);
	$connection->createFunction('concat', 'smf_udf_concat');
	$connection->createFunction('locate', 'smf_udf_locate', 2);<commit_msg>! Add code to remedy "Database Is Locked" errors in SQLite3 per #40 (thanks to @tinoest for the fix)<commit_after><?php

/**
 * This file has all the main functions in it that relate to the database.
 *
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2014 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 Alpha 1
 */

if (!defined('SMF'))
	die('No direct access...');

/**
 *  Maps the implementations in this file (smf_db_function_name)
 *  to the $smcFunc['db_function_name'] variable.
 *
 * @param string $db_server
 * @param string $db_name
 * @param string $db_user
 * @param string $db_passwd
 * @param string $db_prefix
 * @param array $db_options
 */
function smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_options = array())
{
	global $smcFunc, $mysql_set_mode, $db_in_transact, $sqlite_error;

	// Map some database specific functions, only do this once.
	// SQLite3 does not have any procedural functions, so we need to map them all...
	if (!isset($smcFunc['db_fetch_assoc']) || $smcFunc['db_fetch_assoc'] != 'smf_db_fetch_array')
		$smcFunc += array(
			'db_query' => 'smf_db_query',
			'db_quote' => 'smf_db_quote',
			'db_fetch_assoc' => 'smf_db_fetch_array',
			'db_fetch_row' => 'smf_db_fetch_row',
			'db_free_result' => 'smf_db_free_result',
			'db_insert' => 'smf_db_insert',
			'db_insert_id' => 'smf_db_insert_id',
			'db_num_rows' => 'smf_db_num_rows',
			'db_data_seek' => 'smf_db_seek',
			'db_num_fields' => 'smf_db_num_fields',
			'db_escape_string' => 'smf_db_escape_string',
			'db_unescape_string' => 'smf_db_unescape_string',
			'db_server_info' => 'smf_db_libversion',
			'db_affected_rows' => 'smf_db_affected_rows',
			'db_transaction' => 'smf_db_transaction',
			'db_error' => 'smf_db_last_error',
			'db_select_db' => '',
			'db_title' => 'SQLite3',
			'db_sybase' => true,
			'db_case_sensitive' => true,
			'db_escape_wildcard_string' => 'smf_db_escape_wildcard_string',
		);

	if (substr($db_name, -3) != '.db')
		$db_name .= '.db';

	// SQLite3 doesn't support persistent connections...
	$connection = new SQLite3($db_name);

	// Something's wrong, show an error if its fatal (which we assume it is)
	if (!$connection)
	{
		if (!empty($db_options['non_fatal']))
			return null;
		else
			display_db_error();
	}
	$db_in_transact = false;

	// This is frankly stupid - stop SQLite returning alias names!
	@$connection->exec('PRAGMA short_column_names = 1');

	// Make some user defined functions!
	smf_db_define_udfs($connection);

	// Fix for "Database Is Locked" error (measured in ms, so this is 1 second)
	$connection->busyTimeout(1000);
	return $connection;
}

/**
 * Extend the database functionality. It calls the respective file's init
 * to add the implementations in that file to $smcFunc array.
 *
 * @param string $type indicated which additional file to load. ('extra', 'packages')
 */
function db_extend($type = 'extra')
{
	global $sourcedir, $db_type;

	require_once($sourcedir . '/Db' . strtoupper($type[0]) . substr($type, 1) . '-' . $db_type . '.php');
	$initFunc = 'db_' . $type . '_init';
	$initFunc();
}

/**
 * Verify that we have a valid connection
 * 
 * @param resource $connection
 * Thanks to tinoest for this idea
 */
function smf_db_check_connection($connection)
{
	global $db_name;

 	if (!is_object($connection) || is_null($connection))
 	{
 		if (substr($db_name, -3) != '.db')
 			$db_name .= '.db';

		$connection = new Sqlite3($db_name);

		smf_db_define_udfs($connection);

		// Fix for the "Database Is Locked" error (measured in ms, so this is 1 second)
		$connection->busyTimeout(1000);
	}

	return $connection;
}

/**
 * Define user-defined functions for SQLite3
 * @param resource $connection
 */
function smf_db_define_udfs(&$connection)
{
	$connection->createFunction('unix_timestamp', 'smf_udf_unix_timestamp', 0);
	$connection->createFunction('inet_aton', 'smf_udf_inet_aton', 1);
	$connection->createFunction('inet_ntoa', 'smf_udf_inet_ntoa', 1);
	$connection->createFunction('find_in_set', 'smf_udf_find_in_set', 2);
	$connection->createFunction('year', 'smf_udf_year', 1);
	$connection->createFunction('month', 'smf_udf_month', 1);
	$connection->createFunction('dayofmonth', 'smf_udf_dayofmonth', 1);
	$connection->createFunction('concat', 'smf_udf_concat');
	$connection->createFunction('locate', 'smf_udf_locate', 2);
{'fraction_non_alphanumeric': 0.15227430154698685, 'fraction_numerical': 0.00750404063726622, 'mean_word_length': 4.9133105802047785, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '212004', 'n_tokens_mistral': 3349, 'n_tokens_neox': 3131, 'n_words': 714}