← Back to team overview

anewt-developers team mailing list archive

[Branch ~uws/anewt/anewt.uws] Rev 1716: [database.old, autorecord.old] Remove obsolete modules

 

------------------------------------------------------------
revno: 1716
committer: Wouter Bolsterlee <uws@xxxxxxxxx>
branch nick: anewt.uws
timestamp: Sun 2009-08-02 13:07:28 +0200
message:
  [database.old,autorecord.old] Remove obsolete modules
removed:
  autorecord.old/
  autorecord.old/autorecord.lib.php
  autorecord.old/autorecord.test.php
  autorecord.old/main.lib.php
  database.old/
  database.old/backend.lib.php
  database.old/database.lib.php
  database.old/database.test.php
  database.old/main.lib.php
  database.old/module.doc.xml
  database.old/mssql/
  database.old/mssql/backend.lib.php
  database.old/mssql/resultset.lib.php
  database.old/mysql/
  database.old/mysql/backend.lib.php
  database.old/mysql/resultset.lib.php
  database.old/postgresql/
  database.old/postgresql/backend.lib.php
  database.old/postgresql/resultset.lib.php
  database.old/preparedquery.lib.php
  database.old/resultset.lib.php
  database.old/sqlite/
  database.old/sqlite/backend.lib.php
  database.old/sqlite/resultset.lib.php
  database.old/sqlite/test.php
  database.old/sqltemplate.lib.php


--
lp:anewt
https://code.launchpad.net/~uws/anewt/anewt.uws

Your team Anewt developers is subscribed to branch lp:anewt.
To unsubscribe from this branch go to https://code.launchpad.net/~uws/anewt/anewt.uws/+edit-subscription.
=== removed directory 'autorecord.old'
=== removed file 'autorecord.old/autorecord.lib.php'
--- autorecord.old/autorecord.lib.php	2009-03-27 15:49:10 +0000
+++ autorecord.old/autorecord.lib.php	1970-01-01 00:00:00 +0000
@@ -1,1492 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, autorecord module
- *
- * Copyright (C) 2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database');
-
-
-/**
- * Automatic database record object.
- *
- * AutoRecord is an advanced database wrapper class implementing the active
- * record pattern. Each class wraps a single database table, providing you with
- * a convenient search API for querying and easy to use save(), insert() and
- * delete() methods for object manipulation.
- *
- * The query API consists of several static methods:
- *
- * - AutoRecord::find_all() retrieves all records in the database
- * - AutoRecord::find_by_id() and AutoRecord::find_one_by_id() return records
- *   based on the primary key value
- * - AutoRecord::find_by_sql() and AutoRecord::find_one_by_sql() return records
- *   based on constraints expressed as SQL query parts.
- * - AutoRecord::find_by_column() and AutoRecord::find_one_by_column() return
- *   records where a specified column has the specified value.
- *
- * The data manipulation methods are instance methods that operate on object
- * instances themselves:
- *
- * - AutoRecord::save() saves the current record
- * - AutoRecord::delete() deletes the current record
- *
- * In order to create an AutoRecord subclass, you should name your own class
- * <code>Foo_</code> (with a trailing underscore), and override some of the methods
- * (_db_table() and _db_columns() are obligatory). See the documentation on the
- * methods below for more information. Right after your class definition, you
- * should register your AutoRecord subclass so that the actual magic can be put
- * into place: <code>AutoRecord::register('Foo')</code>. Now you can use the
- * <code>Foo</code> class. Example:
- * <code>$somefoo = Foo::find_one_by_id(12)</code>
- *
- * \todo
- *   find_previous() and find_next() methods (based on sort order)
- */
-class AutoRecord extends Container
-{
-	/** \{
-	 * \name Static methods
-	 */
-
-	/**
-	 * Return a reference to the default database connection. Override this
-	 * method if you want to use a custom database instance.
-	 *
-	 * \return
-	 *   A reference to a Database instance
-	 */
-	protected static function _db()
-	{
-		$db = DB::get_instance();
-		return $db;
-	}
-
-	/**
-	 * Return the name of the table to use. You must override this method for
-	 * your own classes. An example might be the following one-liner:
-	 * <code>return 'person';</code>
-	 *
-	 * \return
-	 *   An string with the table name to use
-	 *
-	 * \see AutoRecord::_db_columns
-	 */
-	protected static function _db_table()
-	{
-		throw new Exception('AutoRecord::_db_table() must be overridden.');
-	}
-
-	/**
-	 * Return an associative array of column name => column type mappings. You
-	 * must override this method for your own classes. An example might be the
-	 * following one-liner:
-	 * <code>return array('id' => 'int', 'name' => 'str', 'age' =>
-	 * 'int');</code>
-	 *
-	 * \return
-	 *   An associative array with column name => type items
-	 *
-	 * \see AutoRecord::_db_table
-	 */
-	protected static function _db_columns()
-	{
-		throw new Exception('AutoRecord::_db_columns() must be overridden.');
-	}
-
-	/**
-	 * Return an array of column names which should be skipped on insert queries
-	 * when no values are given. The database is expected to fill a default
-	 * value for these columns.
-	 */
-	protected static function _db_skip_on_insert()
-	{
-		return array();
-	}
-
-	/**
-	 * Return an array of column names which should be skipped on update queries.
-	 * These are usually read-only values which don't need to get updated
-	 * every time.
-	 */
-	protected static function _db_skip_on_update()
-	{
-		return array();
-	}
-
-	/**
-	 * \static \protected
-	 *
-	 * Return an array of column names which are read-only and should never be
-	 * written. The database is expected to fill a default value for these
-	 * columns.
-	 *
-	 * Note that like _db_skip_on_insert the values are still written on an
-	 * insert when they are supplied, but they are never written on an update.
-	 */
-	protected static function _db_skip_on_save()
-	{
-		return array();
-	}
-
-	/**
-	 * \static \protected
-	 *
-	 * Return the name of the primary key. Override this method if you don't
-	 * want to use the default value 'id'.
-	 *
-	 * \return
-	 *   The name of the primary key column
-	 */
-	protected static function _db_primary_key()
-	{
-		return 'id';
-	}
-
-	/**
-	 * Return the name of the sequence used for the primary key (PostgreSQL
-	 * only). Override this function if you're using a non-standard sequence
-	 * for the primary key values of your table.
-	 *
-	 * \return
-	 *   The name of the sequence used for the primary key value
-	 */
-	protected static function _db_primary_key_sequence()
-	{
-		return null;
-	}
-
-	/**
-	 * Return the name of the default sort column. This column is used to sort
-	 * the records in some methods that return multiple columns. If you specify
-	 * order-by parameters to methods, this value is not used, but for simple
-	 * cases like find_all() it serves as the sort column. By default, the
-	 * primary key value is used. Override this method if you want a custom
-	 * column to be used, eg. a position or date column.
-	 *
-	 * It is also possible to order by multiple columns by returning an array
-	 * of columns. In this case you have to override _db_sort_order() as well
-	 * by letting it return an array with the same amount of elements.
-	 *
-	 * Furthermore you can specify table aliasses used in _db_join_one() by
-	 * using "table_alias.column" syntax.
-	 * 
-	 * \return
-	 *   The name of the default sort column or an array of columns in order
-	 *   of high to low priority.
-	 *
-	 * \see AutoRecord::_db_sort_order
-	 */
-	protected static function _db_sort_column()
-	{
-		return null;
-	}
-
-	/**
-	 * Return the default sort order. The value returned by this method should
-	 * be ASC or DESC. The default is ascending sort order. Override this method
-	 * if you want to change it.
-	 *
-	 * If you have overridden _db_sort_column() to return multiple column names,
-	 * then override this method as well to return the same amount of elements.
-	 *
-	 * \return
-	 *   The default sort order (ASC or DESC) or an array of sort orders.
-	 *
-	 * \see AutoRecord::_db_sort_column
-	 */
-	protected static function _db_sort_order()
-	{
-		return 'ASC';
-	}
-
-	/**
-	 * \todo document this
-	 */
-	protected static function _db_has_many()
-	{
-		return array();
-	}
-
-	/**
-	 * \todo document this
-	 */
-	protected static function _db_has_one()
-	{
-		return array();
-	}
-
-	/**
-	 * Override this method if you want the default queries to contain
-	 * joins with other tables, specified by other AutoRecord classes.
-	 * 
-	 * The format is an nummeric array of associative arrays. The
-	 * associative arrays can have the following keys:
-	 * 	foreign_class	- The AutoRecord class which corresponds to the
-	 * 			  other table.
-	 * 	own_key		- (optional) The foreign key in this table to
-	 *			  join on. Use this if the column in this table
-	 *			  doesn't match the primary key of the foreign
-	 *			  table.
-	 * 	foreign_alias	- (optional) The alias name of the other table.
-	 *			  Use this if you want the same table joined
-	 *			  multiple times.
-	 * 	own_alias	- (optional) Use this if 'own_key' is not part
-	 * 			  of the table specified by this class; must be
-	 * 			  a table name, not a class name.
-	 * 	join_type	- (optional) the type of join. Defaults to
-	 * 			  'left', but can be 'right' or 'inner' or
-	 * 			  anything which can go before the "JOIN"
-	 * 			  keyword in the SQL syntax.
-	 * \return
-	 *	A nummeric array of associative arrays.
-	 */
-	protected static function _db_join_one()
-	{
-		return array();
-	}
-
-	/**
-	 * Register a class as an AutoRecord. This does some evil voodoo magic to
-	 * get things to work in a decent way. Your own class name should be called
-	 * Foo_ (with a trailing underscore) and should extend AutoRecord; this
-	 * method will dynamically create a class Foo extending your class with all
-	 * the static methods in place.
-	 *
-	 * \param $class
-	 *   The name of the class to register as an "active record" class (without
-	 *   the trailing underscore)
-	 */
-	public static function register($class)
-	{
-		assert('is_string($class)');
-
-		/* Extreme precautions because eval() is used */
-		if (!preg_match('/^[a-z0-9_]+$/i', $class))
-			trigger_error(sprintf(
-				'AutoRecord::register(): illegal class name \'%s\'',
-				$class), E_USER_ERROR);
-
-		/* There should be a base class with an underscore at the end */
-		if (!class_exists($class . '_'))
-			trigger_error(sprintf(
-				'AutoRecord::register(): class name \'%s_\' does not exist.',
-				$class), E_USER_ERROR);
-
-		/* Some useful variables */
-		$class_ = $class . '_';
-
-		/* Nasty hack to get some static methods in place, providing a nice API.
-		 * Too bad there is no way to retrieve the current class name when
-		 * calling static methods from derived classes (debug_backtrace() can be
-		 * used in PHP4, but this doesn't work for PHP5). */
-
-		$methods = array();
-
-		/* Select clause with all fields */
-		$methods['_db_select_clause'] = 'protected static function _db_select_clause($table_alias=null, $joins=null) {
-			$db = @@CLASS@@::_db();
-			return @@CLASS@@::__db_select_clause(\'@@CLASS@@\', $table_alias, $joins, $db);
-		}';
-
-		/* From clause with all joins */
-		$methods['_db_from_clause'] = 'function _db_from_clause($table_alias=null, $joins=null) {
-			$db = &@@CLASS@@::_db();
-			return @@CLASS@@::__db_from_clause(\'@@CLASS@@\', $table_alias, $joins, $db);
-		}';
-
-		/* Create instances from arrays (e.g. database records) */
-		$methods['_db_object_from_array'] = 'protected static function _db_object_from_array($arr) {
-			$r = @@CLASS@@::__db_object_from_array(\'@@CLASS@@\', $arr);
-			return $r;
-		}';
-		$methods['_db_objects_from_arrays'] = 'protected static function _db_objects_from_arrays($arrs) {
-			$r = @@CLASS@@::__db_objects_from_arrays(\'@@CLASS@@\', $arrs);
-			return $r;
-		}';
-
-		/* Find all */
-		$methods['find_all'] = 'public static function find_all() {
-			$result = @@CLASS@@::find_by_sql();
-			return $result;
-		}';
-
-		/* Find by id */
-		$methods['find_by_id'] = 'public static function find_by_id($values) {
-			$args = func_get_args();
-			$num_args = func_num_args();
-			/* Accept both multiple parameters and a single array */
-			if (($num_args == 1) && is_array($args[0])) {
-				$args = $args[0];
-			}
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_id(\'@@CLASS@@\', false, $args, $db);
-			return $result;
-		}';
-
-		$methods['find_one_by_id'] = 'public static function find_one_by_id($value) {
-			assert(\'is_int($value)\');
-			/* Check for just one single parameter. This helps finding
-			 * bugs where find_by_id() was meant to be used */
-			$num_args = func_num_args();
-			assert(\'$num_args === 1\');
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_id(\'@@CLASS@@\', true, array($value), $db);
-			return $result;
-		}';
-
-		/* Find by SQL */
-		$methods['find_by_sql'] = 'public static function find_by_sql($sql=null, $values=null) {
-			$args = func_get_args();
-			$sql = array_shift($args);
-			if (count($args) == 1 && is_array($args[0])) $args = $args[0];
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_sql(\'@@CLASS@@\', false, $sql, $args, $db);
-			return $result;
-		}';
-		$methods['find_one_by_sql'] = 'public static function find_one_by_sql($sql=null, $values=null) {
-			$args = func_get_args();
-			$sql = array_shift($args);
-			if (count($args) == 1 && is_array($args[0])) $args = $args[0];
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_sql(\'@@CLASS@@\', true, $sql, $args, $db);
-			return $result;
-		}';
-
-		/* Find by column */
-		$methods['find_by_column'] = 'public static function find_by_column($column, $value) {
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_column(\'@@CLASS@@\', false, $column, $value, $db);
-			return $result;
-		}';
-		$methods['find_one_by_column'] = 'public static function find_one_by_column($column, $value) {
-			$db = @@CLASS@@::_db();
-			$result = AutoRecord::__db_find_by_column(\'@@CLASS@@\', true, $column, $value, $db);
-			return $result;
-		}';
-
-		/* Has-many relations */
-		$has_many_definitions = call_user_func(array($class_, '_db_has_many'));
-		foreach ($has_many_definitions as $has_many_definition)
-		{
-			assert('is_numeric_array($has_many_definition)');
-			assert('count($has_many_definition) == 4');
-			list ($method_name, $foreign_class, $local_key, $foreign_key) = $has_many_definition;
-			assert('is_string($method_name)');
-			assert('is_string($foreign_class)');
-			assert('is_string($local_key)');
-			assert('is_string($foreign_key)');
-			$methods[$method_name] = sprintf('
-				var $__autorecord_%s;
-				public function %s()
-				{
-					if (is_null($this->__autorecord_%s))
-						$this->__autorecord_%s = %s::find_by_column(\'%s\', $this->get(\'%s\'));
-
-					return $this->__autorecord_%s;
-				}',
-				$method_name, $method_name, $method_name, $method_name,
-				$foreign_class, $foreign_key, $local_key, $method_name);
-		}
-
-		/* Has-one relations */
-		$has_one_definitions = call_user_func(array($class_, '_db_has_one'));
-		foreach ($has_one_definitions as $has_one_definition)
-		{
-			assert('is_numeric_array($has_one_definition)');
-			assert('count($has_one_definition) == 4');
-			list ($method_name, $foreign_class, $local_key, $foreign_key) = $has_one_definition;
-			assert('is_string($method_name)');
-			assert('is_string($foreign_class)');
-			assert('is_string($local_key)');
-			assert('is_string($foreign_key)');
-			$methods[$method_name] = sprintf('
-				var $__autorecord_%s;
-				public function %s()
-				{
-					if (is_null($this->__autorecord_%s))
-						$this->__autorecord_%s = %s::find_one_by_column(\'%s\', $this->get(\'%s\'));
-
-					return $this->__autorecord_%s;
-				}',
-				$method_name, $method_name, $method_name, $method_name,
-				$foreign_class, $foreign_key, $local_key, $method_name);
-		}
-
-		/* Custom extra methods */
-		$extra_methods = call_user_func(array($class_, '_autorecord_extra_methods'));
-		$methods = array_merge($methods, $extra_methods);
-
-		/* Create the actual class definition string. */
-		$class_code = array();
-		$class_code[] = 'class @@CLASS@@ extends @@CLASS@@_ {';
-		foreach ($methods as $m)
-			$class_code[] = $m;
-
-		$class_code[] = '}';
-
-		/* Replace placeholders with actual values */
-		$class_code = str_replace('@@CLASS@@', $class, join(NL, $class_code));
-
-		/* Actually define the class */
-		eval($class_code);
-	}
-
-	/**
-	 * Create a SQL query part with columns to select. The SELECT keyword is not
-	 * included.
-	 *
-	 * \param $class
-	 *   The class name
-	 *
-	 * \param $table_alias
-	 *   Optional string parameter to use as a table alias. If specified, this
-	 *   string is prepended to all column names. This is useful if you do
-	 *   selects from multiple tables (and identical column names) and you want
-	 *   to select all columns from an AutoRecord table (eg. combined with
-	 *   a join).
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \return
-	 *   String with comma-separated escaped column names. This string can be
-	 *   used directly (unescaped) in the SELECT part of an SQL query.
-	 */
-	protected static function __db_select_clause($class, $table_alias=null, $joins=null, $db)
-	{
-		assert('is_string($class)');
-		assert('$db instanceof DB');
-
-		$column_spec = array();
-		$column_data = array();
-
-		$columns = call_user_func(array($class, '_db_columns'));
-
-		if (is_null($table_alias))
-			$table_alias = call_user_func(array($class, '_db_table'));
-
-		foreach(array_keys($columns) as $column)
-		{
-			$column_spec[] = "?table?.?column?";
-			$column_data[] = $table_alias;
-			$column_data[] = $column;
-		}
-
-		if (is_null($joins)) {
-			$joins = call_user_func(array($class, '_db_join_one'));
-		}
-
-		foreach($joins as $join)
-		{
-			$foreign_class = $join['foreign_class'];
-			$has_alias = false;
-			assert('class_exists($foreign_class); // '.$foreign_class);
-			if (array_has_key($join, 'foreign_alias'))
-			{
-				$foreign_alias = $join['foreign_alias'];
-				$has_alias = true;
-			} else
-				$foreign_alias = call_user_func(array($foreign_class, '_db_table'));
-
-			$columns = call_user_func(array($foreign_class, '_db_columns'));
-			foreach(array_keys($columns) as $column)
-			{
-				if ($has_alias)
-				{
-					$column_spec[] = "?table?.?column? AS ?column?";
-					$column_data[] = $foreign_alias;
-					$column_data[] = $column;
-					$column_data[] = sprintf("%s_%s", $foreign_alias, $column);
-				} else {
-					$column_spec[] = "?table?.?column?";
-					$column_data[] = $foreign_alias;
-					$column_data[] = $column;
-				}
-			}
-		}
-		$tpl = new SQLTemplate(join(",\n  ", $column_spec), $db);
-		return $tpl->fill($column_data);
-	}
-
-	/**
-	 * Create a SQL query part with tables to select from. The FROM keyword
-	 * is not included.
-	 *
-	 * \param $class
-	 *   The class name
-	 *
-	 * \param $table_alias
-	 *   Optional string parameter to use as a table alias.
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \return
-	 *   String with comma-separated escaped table names with join
-	 *   conditions. This string can be used directly (unescaped) in the
-	 *   FROM part of an SQL query.
-	 */
-	protected static function __db_from_clause($class, $table_alias=null, $joins=null, $db)
-	{
-		assert('is_string($class)');
-		assert('$db instanceof DB;');
-
-		$from_clause = $db->backend->escape_table_name(call_user_func(array($class, '_db_table')));
-
-		if (is_null($table_alias))
-			$table_alias = $db->backend->escape_table_name(call_user_func(array($class, '_db_table')));
-		else
-			$from_clause = sprintf('%s %s', $from_clause, $table_alias);
-
-		if (is_null($joins)) {
-			$joins = call_user_func(array($class, '_db_join_one'));
-		}
-
-		foreach ($joins as $join)
-		{
-			$foreign_class = $join['foreign_class'];
-			assert('class_exists($foreign_class)');
-			$join_type = strtoupper(array_get_default($join, 'join_type', 'left'));
-			$foreign_alias = array_get_default($join, 'foreign_alias');
-			$own_alias = array_get_default($join, 'own_alias', $table_alias);
-
-			$foreign_table = $db->backend->escape_table_name(call_user_func(array($foreign_class, '_db_table')));
-			if (array_has_key($join, 'foreign_key'))
-				$foreign_key = $join['foreign_key'];
-			else
-				$foreign_key = call_user_func(array($foreign_class, '_db_primary_key'));
-			$own_key = array_get_default($join, 'own_key', $foreign_key);
-
-			if (is_null($foreign_alias))
-				$foreign_alias = $foreign_table;
-			else
-				$foreign_table = sprintf('%s %s', $foreign_table, $foreign_alias);
-
-			$from_clause = sprintf(
-				"%s\n  %s JOIN %s ON (%s.%s = %s.%s)",
-				$from_clause,
-				$join_type,
-				$foreign_table,
-				$own_alias,
-				$own_key,
-				$foreign_alias,
-				$foreign_key);
-		}
-
-		return $from_clause;
-	}
-
-	/**
-	 * Creates the order by part of an SQL query. The ORDER BY keyword is
-	 * not included.
-	 *
-	 * \param $class
-	 *   The class name
-	 *
-	 * \param $table_alias
-	 *   Optional string parameter to use as a table alias.
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \return
-	 *   String with comma-separated escaped order elements.  This string
-	 *   can be used directly (unescaped) in the FROM part of an SQL query.
-	 */
-	protected static function __db_order_clause($class, $table_alias=null, $db)
-	{
-		if(is_null($table_alias))
-			$table_alias = $db->backend->escape_table_name(call_user_func(array($class, '_db_table')));
-
-		$sort_column = call_user_func(array($class, '_db_sort_column'));
-		if (is_null($sort_column))
-			$sort_column = call_user_func(array($class, '_db_primary_key'));
-
-		if (!is_array($sort_column))
-			$sort_column = array($sort_column);
-
-		$sort_order = call_user_func(array($class, '_db_sort_order'));
-		if (!is_array($sort_order))
-			$sort_order = array($sort_order);
-
-		$order_elements = array();
-		foreach(array_keys($sort_column) as $key)
-		{
-			assert('($sort_order[$key] === "ASC") || ($sort_order[$key] === "DESC")');
-			assert('is_string($sort_column[$key])');
-			$parts = explode(".", $sort_column[$key], 2);
-			if (count($parts) > 1)
-			{
-				$table = $db->backend->escape_table_name($parts[0]);
-				$column = $db->backend->escape_column_name($parts[1]);
-			} else {
-				$table = $table_alias;
-				$column = $db->backend->escape_column_name($sort_column[$key]);
-			}
-			$order_elements[] = $table . "." . $column . " " . $sort_order[$key];
-		}
-
-		return implode(', ', $order_elements);
-	}
-
-	/**
-	 * Converts a result row into an object instance.
-	 *
-	 * \param $class
-	 *   The class name.
-	 *
-	 * \param $row
-	 *   The row with data (or false).
-	 *
-	 * \return
-	 *   A reference to a new instance or null if no data was provided
-	 *
-	 * \see AutoRecord::_db_objects_from_arrays
-	 */
-	protected static function __db_object_from_array($class, $row)
-	{
-		if ($row === false)
-			return null;
-
-		assert('is_assoc_array($row)');
-		$instance = new $class();
-		$instance->_seed($row);
-		return $instance;
-	}
-
-	/**
-	 * Convert result rows into object instances.
-	 *
-	 * \param $class
-	 *   The class name.
-	 *
-	 * \param $rows
-	 *   The rows with data (or an empty array).
-	 *
-	 * \return
-	 *   An array with references to new instances or an empty array no data was provided
-	 *
-	 * \see AutoRecord::__db_object_from_array
-	 */
-	protected static function __db_objects_from_arrays($class, $rows)
-	{
-		assert('is_numeric_array($rows)');
-
-		$result = array();
-		foreach ($rows as $row)
-			$result[] = AutoRecord::__db_object_from_array($class, $row);
-
-		return $result;
-	}
-
-	/**
-	 * Find one or more records by id. Don't use this method directly, use
-	 * find_by_id or find_one_by_id on the class itself.
-	 *
-	 * \param $class
-	 *   The class name.
-	 *
-	 * \param $just_one_result
-	 *   Whether to return just one instance (or null) or an array of instances
-	 *   (possibly empty)
-	 *
-	 * \param $values
-	 *   The values to search for (primary key values)
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \return
-	 *   A single instance (or null) or an array of instances (or empty array)
-	 */
-	protected static function __db_find_by_id($class, $just_one_result, $values, $db)
-	{
-		assert('is_string($class)');
-		assert('is_bool($just_one_result)');
-		assert('is_numeric_array($values)');
-		assert('$db instanceof DB');
-
-		$table = call_user_func(array($class, '_db_table'));
-		$primary_key = call_user_func(array($class, '_db_primary_key'));
-
-		$select_clause = AutoRecord::__db_select_clause($class, null, null, $db);
-		$from_clause = AutoRecord::__db_from_clause($class, null, null, $db);
-
-		/* Single item requested: return an instance or null */
-		if ($just_one_result)
-		{
-			$pq = $db->prepare("SELECT\n  ?raw?\nFROM\n  ?raw?\nWHERE ?table?.?column? = ?int?");
-			$rs = $pq->execute($select_clause, $from_clause, $table, $primary_key, $values[0]);
-			$row = $rs->fetch();
-			$instance = AutoRecord::__db_object_from_array($class, $row);
-			return $instance;
-
-		/* Possibly multiple results: return an array with zero or more instances */
-		} else
-		{
-			/* Return early if there are no id values at all */
-			$num_values = count($values);
-			if ($num_values == 0)
-			{
-				$r = array();
-				return $r;
-			}
-
-			/* Build string for "WHERE id IN (...)" query */
-			$where = join(', ', array_fill(0, $num_values, '?int?'));
-			$tpl = new SQLTemplate($where, $db);
-			$ids = $tpl->fill($values);
-
-			/* Execute */
-			$pq = $db->prepare("SELECT\n  ?raw?\nFROM\n  ?raw?\nWHERE ?table?.?column? IN (?raw?)");
-			$rs = $pq->execute($select_clause, $from_clause, $table, $primary_key, $ids);
-
-			/* Handle results */
-			$rows = $rs->fetch_all();
-			$instances = AutoRecord::__db_objects_from_arrays($class, $rows);
-			return $instances;
-		}
-	}
-
-	/**
-	 * Find one or more records by providing a part of the SQL query. Don't use
-	 * this method directly; use find_by_sql or find_one_by_sql on the instance
-	 * itself.
-	 *
-	 * \param $class
-	 *   The class name.
-	 *
-	 * \param $just_one_result
-	 *   Whether to return just one instance (or null) or an array of instances
-	 *
-	 * \param $sql
-	 *   The constraints of the SQL query. This can be either null (no
-	 *   constraints, selects all records), a string (the part of the WHERE
-	 *   clause up to the end of the query) or an associative array (with
-	 *   join, where, order-by, limit and offset indices, all optional).
-	 *   You can use ?str?-style placholders for the data provided in
-	 *   $values
-	 *
-	 * \param $values
-	 *   The values to be substituted for the placeholders your provided with
-	 *   your constraints.
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 */
-	protected static function __db_find_by_sql($class, $just_one_result=false, $sql=null, $values=null, $db)
-	{
-		/* Input sanitizing */
-		if (is_null($values))
-			$values = array();
-
-		assert('is_string($class)');
-		assert('is_bool($just_one_result)');
-		assert('is_null($sql) || is_string($sql) || is_assoc_array($sql)');
-		assert('is_array($values)');
-		assert('$db instanceof DB');
-
-		/* Get basic database settings */
-		$table = call_user_func(array($class, '_db_table'));
-		$primary_key = call_user_func(array($class, '_db_primary_key'));
-
-		/* Basic clauses */
-		if (is_array($sql))
-			$joins = array_get_default($sql, 'join', null);
-		else
-			$joins = null;
-
-		$select_clause = AutoRecord::__db_select_clause($class, null, $joins, $db);
-
-		$from_clause = AutoRecord::__db_from_clause($class, null, $joins, $db);
-
-		$order_clause = AutoRecord::__db_order_clause($class, null, $db);
-
-		/* Find all records when no sql was specified*/
-		if (is_null($sql))
-		{
-			$pq = $db->prepare("SELECT\n  ?raw?\nFROM\n  ?raw?\nORDER BY ?raw?");
-			$rs = $pq->execute($select_clause, $from_clause, $order_clause);
-
-		/* Plain SQL */
-		} elseif (is_string($sql))
-		{
-			$constraints_tpl = new SQLTemplate($sql, $db);
-			$constraints_sql = $constraints_tpl->fill($values);
-
-			$pq = $db->prepare("SELECT\n  ?raw?\nFROM\n  ?raw?\n?raw?");
-			$rs = $pq->execute($select_clause, $from_clause, $constraints_sql);
-
-		/* Associative array with constraints.
-		 * These may contain both literal values and placeholder strings. It's
-		 * just a fancy way of calling this method with a string parameters
-		 * (useful when using user input). Note that all constraints are treated
-		 * as plain strings. The parameters to be filled in for placeholders in
-		 * these strings should be specified in the $values array. */
-		} else {
-			$constraints = array();
-
-			/* Where. Nothing fancy, just use it. */
-			$where = array_get_default($sql, 'where', null);
-			if (!is_null($where))
-				$constraints[] = sprintf('WHERE %s', $where);
-
-			/* Order by. Both 'order-by' and 'order' keys are recognized. */
-			$order_by = array_get_default($sql, 'order-by', null);
-			if (is_null($order_by))
-				$order_by = array_get_default($sql, 'order', null);
-
-			if (is_null($order_by))
-				$constraints[] = sprintf("\nORDER BY %s", $order_clause);
-			else
-				$constraints[] = sprintf("\nORDER BY %s", $order_by);
-
-			/* Limit. "Optimizing" this depending on the value of
-			 * $just_one_result is impossible since it may contain a placeholder
-			 * string and not a literal value. We take care of $just_one_result
-			 * when fetching the result rows. */
-			$limit = array_get_default($sql, 'limit', null);
-			if (!is_null($limit))
-				$constraints[] = sprintf("\nLIMIT %s", $limit);
-
-			/* Offset. How many rows to skip? */
-			$offset = array_get_default($sql, 'offset', null);
-			if (!is_null($offset))
-				$constraints[] = sprintf("\nOFFSET %s", $offset);
-
-			$constraints_tpl = new SQLTemplate(join(' ', $constraints), $db);
-			$constraints_sql = $constraints_tpl->fill($values);
-
-			$pq = $db->prepare("SELECT\n  ?raw?\nFROM\n  ?raw?\n?raw?");
-			$rs = $pq->execute($select_clause, $from_clause, $constraints_sql);
-		}
-
-		if ($just_one_result)
-		{
-			$row = $rs->fetch();
-			$instance = AutoRecord::__db_object_from_array($class, $row);
-			$rs->free(); // don't need it anymore
-			return $instance;
-		} else {
-			$rows = $rs->fetch_all();
-			$instances = AutoRecord::__db_objects_from_arrays($class, $rows);
-			return $instances;
-		}
-	}
-
-
-	/**
-	 * Find one or more records by one column value. Don't use this method
-	 * directly, use find_by_column or find_one_by_column on the class itself.
-	 *
-	 * \param $class
-	 *   The class name
-	 *
-	 * \param $just_one_result
-	 *   Whether to return just one instance (or null) or an array of instances
-	 *   (possibly empty)
-	 *
-	 * \param $column
-	 *   The column to match
-	 *
-	 * \param $value
-	 *   The value to match
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 */
-	protected static function __db_find_by_column($class, $just_one_result, $column, $value, $db)
-	{
-		/* Input sanitizing */
-		assert('is_string($class)');
-		assert('is_bool($just_one_result)');
-		assert('is_string($column)');
-		assert('$db instanceof DB');
-
-		$table = call_user_func(array($class, '_db_table'));
-
-		/* Find out the column type */
-		$columns = call_user_func(array($class, '_db_columns'));
-		if (!array_has_key($columns, $column))
-			trigger_error(sprintf("Column %s not found in column list of %s", $column, $class));
-
-		/* The array form of __db_find_by_sql is used, so that the default sort
-		 * column is used. If a plain sql string is provided, no sorting will
-		 * be done at all. */
-		if (is_null($value))
-		{
-			$where_clause = '?table?.?column? IS NULL';
-			$placeholder_values = array($table, $column);
-		} else
-		{
-			$where_clause = sprintf('?table?.?column? = ?%s?', $columns[$column]);
-			$placeholder_values = array($table, $column, $value);
-		}
-
-		$result = AutoRecord::__db_find_by_sql(
-				$class,
-				$just_one_result,
-				array('where' => $where_clause),
-				$placeholder_values,
-				$db);
-		return $result;
-	}
-
-
-	/**
-	 * Convert a list of instances to a hash, based on a unique key of the
-	 * passed AutoRecord instances.
-	 *
-	 * \param $objects
-	 *   A list of AutoRecord instances
-	 *
-	 * \param $column
-	 *   The name of the (unique) column to use as the associative array.
-	 *
-	 * \return
-	 *   An associative array with the (unique) column value as the key and the
-	 *   object itself as the value
-	 *
-	 * \see AutoRecord::convert_to_primary_key_hash
-	 */
-	public static function convert_to_key_hash($objects, $column)
-	{
-		assert('is_numeric_array($objects)');
-		assert('is_string($column)');
-
-		/* Handle empty lists */
-		if (count($objects) == 0)
-			return array();
-
-		/* Now iterate over objects and put into hash */
-		$r = array();
-		foreach (array_keys($objects) as $object_key)
-		{
-			assert('$objects[$object_key] instanceof AutoRecord;');
-			$r[$objects[$object_key]->_get($column)] = $objects[$object_key];
-		}
-		return $r;
-	}
-
-	/**
-	 * Convert a list of instances to a hash, based on the primary key of the
-	 * passed AutoRecord instances.
-	 *
-	 * \param $objects
-	 *   A list of AutoRecord instances
-	 *
-	 * \return
-	 *   An associative array with the primary key as the key and the object
-	 *   itself as the value
-	 *
-	 * \see AutoRecord::convert_to_key_hash
-	 */
-	public static function convert_to_primary_key_hash($objects)
-	{
-		assert('is_numeric_array($objects)');
-
-		/* Handle empty lists */
-		if (count($objects) == 0)
-			return array();
-
-		/* Find out the primary key column by looking in the first object */
-		$primary_key_column = $objects[0]->_db_primary_key();
-
-		$r = AutoRecord::convert_to_key_hash($objects, $primary_key_column);
-		return $r;
-	}
-
-	/** \} */
-
-
-	/** \{
-	 * \name Instance methods
-	 */
-
-	/**
-	 * Inserts the data as a new record in the database. Don't use this method
-	 * directly, use save() instead.
-	 *
-	 * \param $skip_primary_key
-	 *	Whether to skip the primary key in the column list.
-	 *
-	 * \see AutoRecord::save
-	 */
-	protected function __db_insert($skip_primary_key=true)
-	{
-		$table = $this->_db_table();
-		$columns = $this->_db_columns();
-		$skip_on_insert = $this->_db_skip_on_insert();
-		$skip_on_save = $this->_db_skip_on_save();
-		$skip_on_insert = array_merge($skip_on_insert, $skip_on_save);
-		$db = $this->_db();
-		$primary_key = $this->_db_primary_key();
-
-		$this->before_insert();
-
-		/* Loop over the columns and build an INSERT query, which contains two
-		 * lists: one list of column names and one list of values to be inserted */
-		$number_of_columns = 0;
-		$names = array();
-		$values = array();
-		foreach ($columns as $name => $type)
-		{
-			assert('is_string($name)');
-			assert('is_string($type)');
-
-			/* Skip the primary key */
-			if ($name === $primary_key && $skip_primary_key)
-				continue;
-
-			/* Skip columns which should be filled by the database */
-			if (in_array($name, $skip_on_insert) && !$this->is_set($name))
-				continue;
-
-			$number_of_columns++;
-			$names[] = $name;
-			$value_types[] = sprintf('?%s:%s?', $type, $name); /* placeholder for real values */
-			$values[$name] = $this->getdefault($name, null);
-		}
-
-		/* Create SQL for the list of column names */
-		$columns_tpl = new SQLTemplate(
-				join(', ', array_fill(0, $number_of_columns, '?column?')),
-			   	$db);
-		$columns_sql = $columns_tpl->fill($names);
-
-		/* Create SQL for the list of column values */
-		$values_tpl = new SQLTemplate(
-				join(', ', $value_types),
-				$db);
-		$values_sql = $values_tpl->fill($values);
-
-
-		/* Prepare and execute the query */
-		$query = sprintf('INSERT INTO ?table? (%s) VALUES (%s)', $columns_sql, $values_sql);
-		$pq = $db->prepare($query);
-		$rs = $pq->execute($table);
-
-		if ($skip_primary_key)
-		{
-			/* Find out the new primary key value */
-			switch ($db->type)
-			{
-				/* MySQL has a custom SQL function */
-				case 'mysql':
-					$row = $db->prepare_execute_fetch(
-							'SELECT LAST_INSERT_ID() AS id');
-					$this->_set($primary_key, $row['id']);
-					break;
-
-				/* SQLite has a special function */
-				case 'sqlite':
-					$this->_set($primary_key, sqlite_last_insert_rowid($db->backend->handle));
-					break;
-
-				/* PostgreSQL uses sequences */
-				case 'postgresql':
-					$primary_key_sequence = $this->_db_primary_key_sequence();
-					if (is_null($primary_key_sequence))
-					{
-						/* Try to use PostgreSQL defaults */
-						$primary_key_sequence = sprintf(
-								'%s_%s_seq',
-								$table,
-								$primary_key);
-					}
-					assert('is_string($primary_key_sequence)');
-					$row = $db->prepare_execute_fetch(
-							'SELECT currval(?string?) AS id',
-							$primary_key_sequence);
-					$this->_set($primary_key, $row['id']);
-					break;
-
-				/* Fallback for unsupported backends */
-				default:
-					$row = $db->prepare_execute_fetch(
-							'SELECT MAX(?column?) AS id FROM ?table?',
-							$primary_key, $table);
-					$this->_set($primary_key, $row['id']);
-					break;
-			}
-		}
-
-		$this->after_insert();
-	}
-
-	/**
-	 * Updates an existing record in the database with the current instance
-	 * data. Don't use this method directly, use save() instead.
-	 *
-	 * \see AutoRecord::save
-	 */
-	protected function __db_update()
-	{
-		$table = $this->_db_table();
-		$columns = $this->_db_columns();
-		$db = $this->_db();
-		$skip_on_update = $this->_db_skip_on_update();
-		$skip_on_save = $this->_db_skip_on_save();
-		$skip_on_update = array_merge($skip_on_update, $skip_on_save);
-		$primary_key = $this->_db_primary_key();
-		$primary_key_value = $this->get($primary_key);
-
-		$this->before_update();
-
-		/* Loop over the columns and build an UPDATE query */
-		$placeholders = array();
-		$values = array();
-		foreach ($columns as $name => $type)
-		{
-			assert('is_string($name)');
-			assert('is_string($type)');
-
-			/* Skip the primary key */
-			if ($name === $primary_key)
-				continue;
-
-			/* Skip read-only values */
-			if (in_array($name, $skip_on_update))
-				continue;
-
-			$placeholders[] = sprintf('%s = ?%s:%s?', $db->backend->escape_column_name($name), $type, $name);
-			$values[$name] = $this->getdefault($name, null);
-		}
-
-		if(count($placeholders))
-		{
-			/* Create SQL for the list of column names */
-			$update_tpl = new SQLTemplate(join(', ', $placeholders), $db);
-			$update_sql = $update_tpl->fill($values);
-	
-			/* Prepare and execute the query */
-			$pq = $db->prepare('UPDATE ?table? SET ?raw? WHERE ?column? = ?int?');
-			$rs = $pq->execute($table, $update_sql, $primary_key, $primary_key_value);
-		}
-
-		$this->after_update();
-	}
-
-	/**
-	 * Save this record in the database. If the record was previously unsaved
-	 * (no primary key value was set), an INSERT query is performed. Otherwise,
-	 * an UPDATE on the existing row is done.
-	 *
-	 * \param new
-	 *   Whether or not we should insert a new row. Leave empty to check on the
-	 *   primary key.
-	 */
-	public function save($new=null)
-	{
-		$this->before_save();
-
-		if (is_null($new))
-		{
-			/* Default behaviour */
-			$primary_key = $this->_db_primary_key();
-			if ($this->is_set($primary_key))
-				$this->__db_update();
-			else
-				$this->__db_insert();
-		} else
-		{
-			/* Forced new/existing record */
-			if ($new)
-				$this->__db_insert(false);
-			else
-				$this->__db_update();
-		}
-
-		$this->after_save();
-	}
-
-	/**
-	 * Delete this record from the database. If the record was previously
-	 * unsaved, this is a no-op. Note that this method overrides
-	 * Container::delete() (and Container::invalidate()). If you provide
-	 * a parameter, the call is handed off to Container::delete() instead of
-	 * deleting the record from the database.
-	 *
-	 * \param $name
-	 *   Do not specify this! It's for code compatibility with Container only.
-	 *
-	 * \fixme See bug 173044
-	 */
-	public function delete($name=null)
-	{
-		/* If there are any parameters, we propagate the call to Container,
-		 * instead of deleting the record from the database. This is evil and
-		 * should be solved in a clean way. See bug 173044. */
-		if (!is_null($name))
-			return Container::delete($name);
-
-		$this->before_delete();
-
-		$primary_key = $this->_db_primary_key();
-		if ($this->is_set($primary_key))
-		{
-			$primary_key_value = $this->get($primary_key);
-			$db = $this->_db();
-			$table = $this->_db_table();
-			$db->prepare_execute(
-				'DELETE FROM ?table? WHERE ?column? = ?int?;',
-				$table, $primary_key, $primary_key_value);
-		}
-
-		$this->after_delete();
-	}
-
-	/**
-	 * Toggle a boolean value in this record. If the value was previously unset
-	 * (SQL NULL), the value is initialized to true.
-	 *
-	 * \param $column
-	 *   The name of the column to toggle.
-	 */
-	public function toggle($column)
-	{
-		assert('is_string($column)');
-		$columns = $this->_db_columns();
-		assert('array_has_key($columns, $column)');
-		assert('SQLTemplate::column_type_from_string($columns[$column]) == ANEWT_DATABASE_TYPE_BOOLEAN;');
-
-		$current_value = $this->getdefault($column, null);
-		if (is_null($current_value))
-			$new_value = true;
-
-		else
-		{
-
-			/* Handle strings and integers, because some databases don't support
-			 * boolean column types (MySQL) and others don't support column
-			 * types at all (SQLite). */
-			if (is_int($current_value))
-				$current_value = (bool) $current_value;
-			elseif (is_string($current_value))
-				$current_value = ($current_value !== '0');
-
-			assert('is_bool($current_value)');
-			$new_value = !$current_value;
-		}
-		$this->set($column, $new_value);
-	}
-
-	/** \} */
-
-
-	/**
-	 * \{
-	 * \name Callback methods
-	 *
-	 * Callback methods that can be overridden to add specific functionality.
-	 *
-	 * Autorecord instances call some special callback methods when certain
-	 * actions are about to take place (e.g. AutoRecord::before_save()) or have
-	 * just taken place (e.g. AutoRecord::after_delete). These methods do
-	 * nothing by default, but you can override one or more of them in your own
-	 * classes if you want to do specific things, e.g. to fix up values before
-	 * they enter the database (but you should really consider using
-	 * Container::get() and Container::set() for this purpose) or to break
-	 * foreign key references.
-	 */
-
-	/** Callback before saving */
-	public function before_save() {}
-
-	/** Callback after saving */
-	public function after_save() {}
-
-	/** Callback before inserting */
-	public function before_insert() {}
-
-	/** Callback after inserting */
-	public function after_insert() {}
-
-	/** Callback before updating */
-	public function before_update() {}
-
-	/** Callback after updating */
-	public function after_update() {}
-
-	/** Callback before deletion */
-	public function before_delete() {}
-
-	/** Callback after deletion */
-	public function after_delete() {}
-
-	/** \} */
-
-
-	/**\{
-	 * \name Static public API methods
-	 *
-	 * Note: These methods only have signatures, so that they can be documented.
-	 * The actual implementation is done using magic in the register() method.
-	 */
-
-	/**
-	 * Select clause with all fields
-	 */
-	protected static function _db_select_clause($table_alias=null) {}
-
-	/**
-	 * Create instance from array.
-	 *
-	 * \param $arr
-	 *   An associative array with data, e.g. a row from a database
-	 *
-	 * \return
-	 *   AutoRecord instance
-	 *
-	 * \see _db_objects_from_arrays
-	 */
-	protected static function _db_object_from_array($arr) {}
-
-	/**
-	 * Create instances from arrays.
-	 *
-	 * \param $arrs
-	 *   List of associative arrays with data, e.g. multiple rows from
-	 *   a database
-	 *
-	 * \return
-	 *   Array of AutoRecord instances (may be empty)
-	 *
-	 * \see _db_object_from_array
-	 */
-	protected static function _db_objects_from_arrays($arrs) {}
-
-	/**
-	 * Find all records in the database
-	 * 
-	 * \return
-	 *   Array of AutoRecord instances (may be empty)
-	 */
-	public static function find_all() {}
-
-	/**
-	 * Find records by id.
-	 *
-	 * \param $values
-	 *   The primary key values of the records to retrieve
-	 *
-	 * \return
-	 *   Array of AutoRecord instances (may be empty)
-	 *
-	 * \see find_one_by_id
-	 */
-	public static function find_by_id($values) {}
-
-	/**
-	 * Find a single record by id.
-	 *
-	 * \param $value
-	 *   The primary key value of the record to retrieve
-	 *
-	 * \return
-	 *   AutoRecord instance (or NULL)
-	 *
-	 * \see find_by_id
-	 */
-	public static function find_one_by_id($value) {}
-
-	/**
-	 * Find records by providing SQL contraints.
-	 *
-	 * \param $sql
-	 *   The constraints of the SQL query. This can be either null (no
-	 *   constraints, selects all records, but please use find_all() instead),
-	 *   a string (the part of the WHERE clause up to the end of the query) or
-	 *   an associative array (with where, order-by, limit and offset indices,
-	 *   all optional). You can use ?str?-style placholders for the data
-	 *   provided in $values
-	 *
-	 * \param $values
-	 *   The values to be substituted for the placeholders your provided with
-	 *   the constraints.
-	 *
-	 * \see find_one_by_sql
-	 */
-	public static function find_by_sql($sql=null, $values=null) {}
-
-	/**
-	 * Find a single record by providing SQL contraints.
-	 *
-	 * \param $sql
-	 *   Contraints of the SQL query
-	 *
-	 * \param $values
-	 *   Values to be substituted in the query
-	 *
-	 * \return
-	 *   AutoRecord instance (or NULL)
-	 *
-	 * \see find_by_sql
-	 */
-	public static function find_one_by_sql($sql=null, $values=null) {}
-
-	/**
-	 * Find records by column value. This is a shorthand to find records based
-	 * on the value of a single column, e.g. a unique key.
-	 *
-	 * \param $column
-	 *   The name of the column to use
-	 *
-	 * \param $value
-	 *   The value for the column
-	 *
-	 * \return
-	 *   Array of AutoRecord instances (may be empty)
-	 */
-	public static function find_by_column($column, $value) {}
-
-	/**
-	 * Find a single record by column value. This is a shorthand to find a record
-	 * based on the value of a single column, e.g. a unique key.
-	 *
-	 * \param $column
-	 *   The name of the column to use
-	 *
-	 * \param $value
-	 *   The value for the column
-	 *
-	 * \return
-	 *   AutoRecord instance (or NULL)
-	 */
-	public static function find_one_by_column($column, $value) {}
-
-	/**
-	 * Returns an array of additional static methods to be included in the new class
-	 * on registering.
-	 *
-	 * The format of the array elements is $method_name => $method_code, where
-	 * $method_name is the name of the method, en $method_code is a string containing
-	 * the code of the method, including the "function" keyword.
-	 *
-	 * Every instance of @@CLASS@@ in $method_code will be substituted for the class
-	 * name of the registring function.
-	 */
-	protected static function _autorecord_extra_methods() { return array(); }
-
-	/** \} */
-}
-
-?>

=== removed file 'autorecord.old/autorecord.test.php'
--- autorecord.old/autorecord.test.php	2009-03-27 12:12:33 +0000
+++ autorecord.old/autorecord.test.php	1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
-<?php
-
-error_reporting(E_ALL | E_STRICT);
-require_once '../anewt.lib.php';
-
-anewt_include('autorecord');
-
-/**
- * Sample Person class with a simple database schema
- */
-class Person_ extends AutoRecord
-{
-	/**
-	 * Table name
-	 */
-	static function _db_table()
-	{
-		return 'person';
-	}
-
-	/**
-	 * Default sort column
-	 */
-	static function _db_sort_column()
-	{
-		return 'age';
-	}
-
-	/**
-	 * Simple database layout
-	 */
-	static function _db_columns()
-	{
-		return array(
-			'id' => 'integer',
-			'name' => 'string',
-			'age' => 'integer',
-			'is_happy' => 'boolean',
-		);
-	}
-}
-
-/* Register the Person/Person_ class as an AutoRecord */
-AutoRecord::register('Person');
-
-
-/* Database connection (in-memory SQLite database) */
-$db = DB::get_instance('sqlite', array(
-			'filename' => ':memory:',
-			'debug' => true,
-			'debug_print' => true,
-			));
-
-/* Create the schema (sqlite ignores column types, though) */
-$db->prepare_execute('CREATE TABLE Person (
-	id INTEGER PRIMARY KEY,
-	name VARCHAR(255),
-	age INTEGER,
-	is_happy BOOLEAN
-	)');
-
-$pq = $db->prepare('INSERT INTO Person (id, name, age, is_happy) VALUES (?int?, ?str?, ?int?, ?bool?)');
-$pq->execute(1, 'A', 10, true);
-$pq->execute(2, 'B', 11, false);
-$pq->execute(3, 'C', 12, false);
-$pq->execute(4, 'D', 13, null);
-$pq->execute(5, 'E', 14, false);
-
-
-
-/* Test the AutoRecord retrieval methods */
-
-$result = Person::find_one_by_id(2);
-// $result = Person::find_by_id(2);
-// $result = Person::find_by_id(array(2, 4));
-// $result = Person::find_by_id(2, 3);
-
-// $result = Person::find_all();
-// $result = Person::find_by_sql();
-// $result = Person::find_by_sql('WHERE id > ?int? ORDER BY age DESC LIMIT ?int?', 2, 2);
-// $result = Person::find_one_by_sql(array(
-// 			'where' => 'id > ?int?',
-// 			'order-by' => 'age DESC',
-// 			'limit' => '?int?',
-// 			), 1, 3);
-
-var_dump($result);
-
-/* Test the save (update/insert) and delete methods */
-
-$p1 = Person::find_one_by_id(1);
-$p1->set('name', 'John');
-$p1->set('age', '12');
-$p1->save();
-
-$p2 = new Person();
-$p2->set('name', 'Foo');
-$p2->set('age', '2');
-$p2->set('is_happy', true);
-$p2->save();
-
-/* Test toggle() */
-
-$p1->toggle('is_happy');
-$p1->save();
-
-$p2->toggle('is_happy');
-$p2->save();
-
-
-/* Dump all data in the person table */
-$rows = $db->prepare_execute_fetch_all('SELECT * FROM person');
-foreach ($rows as $row) {
-	echo array_format($row), "\n";
-}
-
-?>

=== removed file 'autorecord.old/main.lib.php'
--- autorecord.old/main.lib.php	2006-08-07 16:03:31 +0000
+++ autorecord.old/main.lib.php	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, autorecord module
- *
- * Copyright (C) 2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('autorecord/autorecord');
-
-?>

=== removed directory 'database.old'
=== removed file 'database.old/backend.lib.php'
--- database.old/backend.lib.php	2009-03-26 16:47:17 +0000
+++ database.old/backend.lib.php	1970-01-01 00:00:00 +0000
@@ -1,209 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2004-2005  Jasper Looije <jasper@xxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-/**
- * Base class for database backends. Most methods should be overridden in
- * subclasses that implement a specific backend.
- */
-abstract class DatabaseBackend
-{
-	var $db; /**< \private Database object instance */
-
-	/**
-	 * Returns the type of the database (must be overridden).
-	 */
-	abstract function get_type();
-
-
-	/* Connection handling */
-
-	/**
-	 * Sets up the settings when using a deferred connection. Can be overridden.
-	 */
-	function setup($settings) { }
-	
-	/**
-	 * Connects to the database.
-	 *
-	 * \param $settings
-	 *   The database settings as an associative array.
-	 */
-	abstract function connect(array $settings);
-
-	/**
-	 * Disconnects from the database.
-	 */
-	abstract function disconnect();
-
-	/**
-	 * Selects the database to use.
-	 *
-	 * \param $name
-	 *   The name of teh database to use.
-	 */
-	abstract function select_db($name);
-
-
-	/* Escaping */
-
-	/**
-	 * Escapes a boolean for use in SQL queries. Override this method if the
-	 * specific type of database has better escaping functions available.
-	 *
-	 * \param $bool
-	 *   The boolean to escape.
-	 *
-	 * \return
-	 *   The escaped value.
-	 */
-	function escape_boolean($bool)
-	{
-		assert('is_bool($bool)');
-		return $bool ? '1' : '0';
-	}
-
-	/**
-	 * Escapes a string for use in SQL queries. Override this method if the
-	 * specific type of database has better escaping functions available.
-	 *
-	 * \param $str
-	 *   The string to escape.
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function escape_string($str)
-	{
-		assert('is_string($str)');
-		return sprintf("'%s'", addslashes($str));
-	}
-
-	/**
-	 * Escapes a table name for use in SQL queries. Override this method if the
-	 * specific type of database has better escaping functions available.
-	 *
-	 * \param $str
-	 *   The string to escape.
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function escape_table_name($str)
-	{
-		assert('is_string($str)');
-		return $str;
-	}
-
-	/**
-	 * Escapes a column name for use in SQL queries. Override this method if the
-	 * specific type of database has better escaping functions available.
-	 *
-	 * \param $str
-	 *   The string to escape.
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function escape_column_name($str)
-	{
-		assert('is_string($str)');
-		return $str;
-	}
-
-	/**
-	 * Escapes a date. This method only adds quotes.
-	 *
-	 * \param $date
-	 *   The value to escape.
-	 *
-	 * \return
-	 *   The escaped value.
-	 */
-	function escape_date($date)
-	{
-		assert('is_string($date)');
-		return sprintf("'%s'", $date);
-	}
-
-	/**
-	 * Escapes a time. This method only adds quotes.
-	 *
-	 * \param $time
-	 *   The value to escape.
-	 *
-	 * \return
-	 *   The escaped value.
-	 */
-	function escape_time($time)
-	{
-		assert('is_string($time)');
-		return sprintf("'%s'", $time);
-	}
-
-	/**
-	 * Escapes a datetime. This method only adds quotes.
-	 *
-	 * \param $datetime
-	 *   The value to escape.
-	 *
-	 * \return
-	 *   The escaped value.
-	 */
-	function escape_datetime($datetime)
-	{
-		assert('is_string($datetime)');
-		return sprintf("'%s'", $datetime);
-	}
-
-	/* Transaction-related methods */
-
-	/**
-	 * Starts a transaction. Override this method for backends that need
-	 * customization.
-	 */
-	function transaction_begin()
-	{
-		$this->db->prepare_execute('BEGIN');
-	}
-
-	/**
-	 * Commits a transaction. Override this method for backends that need
-	 * customization.
-	 */
-	function transaction_commit()
-	{
-		$this->db->prepare_execute('COMMIT');
-	}
-
-	/**
-	 * Rolls back a transaction. Override this method for backends that need
-	 * customization.
-	 */
-	function transaction_rollback()
-	{
-		$this->db->prepare_execute('ROLLBACK');
-	}
-}
-
-?>

=== removed file 'database.old/database.lib.php'
--- database.old/database.lib.php	2009-03-27 15:48:32 +0000
+++ database.old/database.lib.php	1970-01-01 00:00:00 +0000
@@ -1,375 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2004-2005  Jasper Looije <jasper@xxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/backend');
-anewt_include('database/sqltemplate');
-anewt_include('database/preparedquery');
-anewt_include('database/resultset');
-
-
-/**
- * Database connection class.
- *
- * This class is used to represent a database connection. It support multiple
- * backends.
- *
- * This class provides a get_instance convenience method that eases development
- * with just one database connection (as is the case with almost all
- * applications).
- */
-class DB
-{
-	/* Static methods */
-
-	/**
-	 * Obtain a database instance. This method is modeled after the singleton
-	 * design pattern, but you will need to initialize it with the connection
-	 * settings. The first call to this method will initialize the database with
-	 * the provided settings. Subsequent files return a reference to the
-	 * database instance (and paramaters are ignored).
-	 *
-	 * \param $type
-	 *   The type of database to be used.
-	 *
-	 * \param $settings
-	 *   An associative array of connection settings.
-	 *
-	 * \see DB
-	 * \see DB::connect
-	 */
-	static function get_instance($type=null, $settings=null)
-	{
-		static $db;
-
-		if (is_null($db))
-		{
-			if (is_null($type))
-				trigger_error('Cannot create instance of DB, no type is specified.', E_USER_ERROR);
-
-			$db = new DB($type);
-
-			if (!is_null($settings))
-				$db->settings = $settings;
-		}
-
-		return $db;
-	}
-
-
-	/* Instance variables and methods */
-
-	var $type;                         /**< \private Type of database being used */
-	var $backend;                      /**< \private Database backend instance */
-	var $databasename;                 /**< \private Current database name */
-	var $connected;                    /**< \private Boolean indication the connection status */
-	var $last_query;                   /**< \private Last query executed */
-	var $num_queries_executed = 0;     /**< \private Counter for the number of queries executed */
-	var $settings;                     /**< \private Settings for DB::setup($settings) */
-
-
-	/* Debugging */
-	var $debug = false;                /**< \private Enable/disable debugging */
-	var $debug_print = false;          /**< \private Print queries before execution */
-	var $queries_executed = array();   /**< \private List of executed queries (only used
-										 if debugging is on)*/
-
-	/**
-	 * Constructor initalizes the database layer.
-	 *
-	 * \param $type
-	 *   The type of database to be used (e.g. \c mysql or \c sqlite).
-	 *
-	 * \param $settings
-	 *   Optional argument to be passed to connect().
-	 *
-	 * \see connect
-	 */
-	function DB($type='mysql', $settings=null)
-	{
-		assert('is_string($type)');
-
-		/* Initialize the backend */
-		anewt_include(sprintf('database/%s/backend', $type));
-		$dbtype = ucfirst(strtolower($type)) . 'DB';
-		$this->backend = new $dbtype();
-		$this->backend->db = $this;
-		$this->type = $type;
-
-		/* Initial connection */
-		$this->connected = false;
-		if (!is_null($settings))
-		{
-			$settings['type'] = $type;
-			$this->connect($settings);
-		}
-	}
-
-	/**
-	 * Prepares the database layer for deferred connection.
-	 *
-	 * \param $settings
-	 *   Associative array of connection settings.
-	 */
-	function setup($settings)
-	{
-		assert('is_assoc_array($settings)');
-		$dbtype = array_get_default($settings, 'type', 'mysql');
-		$db = DB::get_instance($dbtype, $settings);
-		return $db;
-	}
-	
-	/**
-	 * Connects to the database using the specified connection settings.
-	 *
-	 * \param $settings
-	 *   An associative array of connection settings. Set the \c debug and
-	 *   \c debug_print keys to true if you want to debug your queries.
-	 */
-	function connect($settings=null)
-	{
-		/* Connect only once */
-		if (!$this->connected)
-		{
-			if (is_null($settings))
-			{
-				if (is_null($this->settings))
-					trigger_error('Cannot connect to database, no settings are specified.', E_USER_ERROR);
-
-				$settings = $this->settings;
-			}
-			assert('is_assoc_array($settings)');
-			$this->backend->connect($settings);
-			$this->connected = true;
-			$this->debug = array_get_default($settings, 'debug', false);
-			$this->debug_print = array_get_default($settings, 'debug_print', false);
-			unset($this->settings);
-		}
-	}
-
-	/**
-	 * Disconnects from the database. Not calling this method is harmless for
-	 * most database backends.
-	 */
-	function disconnect()
-	{
-		if ($this->connected)
-		{
-			$this->backend->disconnect();
-			$this->connected = false;
-		}
-	}
-
-	/**
-	 * Selects the database to be used
-	 *
-	 * \param $name
-	 *   The database name.
-	 */
-	function select_db($name)
-	{
-		assert('is_string($name)');
-		$this->backend->select_db($name);
-		$this->databasename = $name;
-	}
-
-	/** \{
-	 * \name Query methods
-	 */
-
-	/**
-	 * Prepares a query for execution.
-	 *
-	 * \param $sql
-	 *   The SQL query to be prepared. Use <code>?fieldtype?</code> strings.
-	 *
-	 * \return
-	 *   A new PreparedQuery instance that can be executed.
-	 */
-	function prepare($sql)
-	{
-		is_string($sql) && (strlen($sql)>0)
-			or trigger_error('DB::prepare() needs a string parameter',
-					E_USER_ERROR);
-
-		$pq = new PreparedQuery($sql, $this);
-		$pq->debug = $this->debug;
-		$pq->debug_print = $this->debug_print;
-		return $pq;
-	}
-
-	/**
-	 * Convenience method to quickly execute a single query and fetch all
-	 * resulting rows from the result set. If you want to use a query multiple
-	 * times, you should obtain a PreparedQuery object by calling the prepare()
-	 * method, execute it and operate on the ResultSet object.
-	 *
-	 * \param $sql
-	 *   The SQL query to execute. Placeholders (e.g. <code>?int?</code>) should be used.
-	 *
-	 * \param $params
-	 *   Zero or more parameters to be filled in in the $query. The number of
-	 *   parameters should match the number of placeholders in $query
-	 *
-	 * \see DB::prepare_execute
-	 * \see DB::prepare_execute_fetch
-	 * \see DB::prepare
-	 * \see PreparedQuery
-	 * \see ResultSet::fetch_all
-	 */
-	function prepare_execute_fetch_all($sql, $params=null)
-	{
-		$args = func_get_args();
-		assert('count($args) >= 1');
-		array_shift($args); // remove first argument (sql query)
-
-		if ((count($args) == 1) && (is_array($args[0]) || $args[0] instanceof Container))
-			$args = $args[0];
-
-		$pq = $this->prepare($sql);
-		$rs = $pq->execute($args);
-		return $rs->fetch_all();
-	}
-
-	/**
-	 * Convenience method to quickly execute a single query and fetch one
-	 * resulting row from the result set. See DB::prepare_execute_fetch_all for
-	 * more information.
-	 *
-	 * \param
-	 *   $sql The SQL query to execute.
-	 *
-	 * \param
-	 *   $params Zero or more parameters to be filled in in the $query.
-	 *
-	 * \see DB::prepare_execute
-	 * \see DB::prepare_execute_fetch_all
-	 * \see DB::prepare
-	 * \see PreparedQuery
-	 * \see ResultSet::fetch_all
-	 */
-	function prepare_execute_fetch($sql, $params=null)
-	{
-		$args = func_get_args();
-		assert('count($args) >= 1');
-		array_shift($args); // remove first argument (sql query)
-
-		if ((count($args) == 1) && (is_array($args[0]) || $args[0] instanceof Container))
-			$args = $args[0];
-
-		$pq = $this->prepare($sql);
-		$rs = $pq->execute($args);
-		$row = $rs->fetch();
-		$rs->free();
-		return $row;
-	}
-
-	/**
-	 * Convenience method to quickly execute a single query. No results are
-	 * retrieved. This method is pretty useless for SELECT queries, the number
-	 * of affected rows is returned instead of result rows. See
-	 * DB::prepare_execute_fetch_all for more information.
-	 *
-	 * \param $sql
-	 *   The SQL query to execute.
-	 *
-	 * \param $params
-	 *   Zero or more parameters to be filled in in the $query.
-	 *
-	 * \return
-	 *   The number of rows affected by the query. This only works for queries
-	 *   that operate on a number of rows, i.e. \c INSERT, \c UPDATE, \c
-	 *   REPLACE, and \c DELETE queries. For other query types \c null is
-	 *   returned.
-	 *
-	 * \see DB::prepare_execute_fetch
-	 * \see DB::prepare_execute_fetch_all
-	 * \see DB::prepare
-	 * \see PreparedQuery
-	 * \see ResultSet::fetch_all
-	 */
-	function prepare_execute($sql, $params=null)
-	{
-		$args = func_get_args();
-		assert('count($args) >= 1');
-		array_shift($args); // remove first argument (sql query)
-
-		if ((count($args) == 1) && (is_array($args[0]) || $args[0] instanceof Container))
-			$args = $args[0];
-
-		$pq = $this->prepare($sql);
-		$rs = $pq->execute($args);
-
-		$query_type = $rs->query_type();
-		$ret = null;
-		switch ($query_type)
-		{
-			case ANEWT_DATABASE_SQL_QUERY_TYPE_INSERT:
-			case ANEWT_DATABASE_SQL_QUERY_TYPE_UPDATE:
-			case ANEWT_DATABASE_SQL_QUERY_TYPE_REPLACE:
-			case ANEWT_DATABASE_SQL_QUERY_TYPE_DELETE:
-				$ret = $rs->count_affected();
-				break;
-
-			default:
-				/* Return nothing */
-				break;
-		}
-		$rs->free();
-		return $ret;
-	}
-
-	/** \} */
-
-	/** \{
-	 * \name Transaction methods
-	 */
-
-	/**
-	 * Starts a transaction. This method calls into the backend.
-	 */
-	function transaction_begin()
-	{
-		$this->backend->transaction_begin();
-	}
-
-	/**
-	 * Commits a transaction. This method calls into the backend.
-	 */
-	function transaction_commit()
-	{
-		$this->backend->transaction_commit();
-	}
-
-	/**
-	 * Rolls back a transaction. This method calls into the backend.
-	 */
-	function transaction_rollback()
-	{
-		$this->backend->transaction_rollback();
-	}
-
-	/** \} */
-}
-
-?>

=== removed file 'database.old/database.test.php'
--- database.old/database.test.php	2008-11-10 15:05:48 +0000
+++ database.old/database.test.php	1970-01-01 00:00:00 +0000
@@ -1,313 +0,0 @@
-<?php
-
-error_reporting(E_ALL | E_STRICT);
-require_once '../anewt.lib.php';
-
-anewt_include('database');
-
-$db = new DB('sqlite', array(
-			'filename' => ':memory:',
-			'debug' => true,
-			'debug_print' => false,
-			));
-
-$db->transaction_begin();
-$db->prepare_execute('CREATE TABLE typetesttable (
-			boolean_col,
-			integer_col,
-			float_col,
-			string_col,
-			date_col,
-			datetime_col,
-			timestamp_col,
-			time_col,
-			raw_col)');
-$pq = $db->prepare('INSERT INTO typetesttable VALUES ( ?bool?, ?int?, ?float?, ?string?, ?date?, ?datetime?, ?timestamp?, ?time?, ?raw?)');
-
-/* Test null */
-$pq->execute(null, null, null, null, null, null, null, null, null);
-
-/* Test booleans */
-$pq->execute(true, null, null, null, null, null, null, null, null);
-$pq->execute(false, null, null, null, null, null, null, null, null);
-//$pq->execute('foo', null, null, null, null, null, null, null, null);
-
-/* Test ints */
-$pq->execute(null, 2, null, null, null, null, null, null, null);
-$pq->execute(null, '3', null, null, null, null, null, null, null);
-//$pq->execute(null, 'foo', null, null, null, null, null, null, null);
-
-/* Test floats */
-$pq->execute(null, null, 2.0, null, null, null, null, null, null);
-$pq->execute(null, null, 1.234, null, null, null, null, null, null);
-$pq->execute(null, null, 3, null, null, null, null, null, null);
-//$pq->execute(null, null, 'foo', null, null, null, null, null, null);
-
-/* Test strings */
-class StringWrap { function render() {return 'test';} }
-$pq->execute(null, null, null, 'Test', null, null, null, null, null);
-$pq->execute(null, null, null, 'Te\';st', null, null, null, null, null);
-$pq->execute(null, null, null, "\t\n;--'", null, null, null, null, null);
-$pq->execute(null, null, null, 2, null, null, null, null, null);
-$pq->execute(null, null, null, new StringWrap(), null, null, null, null, null);
-//$pq->execute(null, null, null, true, null, null, null, null, null);
-//$pq->execute(null, null, null, 1.234, null, null, null, null, null);
-
-/* Test dates */
-$pq->execute(null, null, null, null, '2006-06-06', null, null, null, null);
-$pq->execute(null, null, null, null, AnewtDateTime::now(), null, null, null, null);
-//$pq->execute(null, null, null, null, 'foo', null, null, null, null);
-//$pq->execute(null, null, null, null, true, null, null, null, null);
-//$pq->execute(null, null, null, null, 2, null, null, null, null);
-
-/* Test datetimes */
-$pq->execute(null, null, null, null, null, '2006-06-06 06:06:06', null, null, null);
-$pq->execute(null, null, null, null, null, AnewtDateTime::now(), null, null, null);
-$pq->execute(null, null, null, null, null, AnewtDateTime::sql(AnewtDateTime::now()), null, null, null);
-//$pq->execute(null, null, null, null, null, 'foo', null, null, null);
-//$pq->execute(null, null, null, null, null, true, null, null, null);
-//$pq->execute(null, null, null, null, null, 2, null, null, null);
-
-/* Test timestamps */
-$pq->execute(null, null, null, null, null, null, '2006-06-06 06:06:06', null, null);
-$pq->execute(null, null, null, null, null, null, AnewtDateTime::now(), null, null);
-$pq->execute(null, null, null, null, null, null, AnewtDateTime::sql(AnewtDateTime::now()), null, null);
-//$pq->execute(null, null, null, null, null, null, 'foo', null, null);
-//$pq->execute(null, null, null, null, null, null, true, null, null);
-//$pq->execute(null, null, null, null, null, null, 2, null, null);
-
-/* Test times */
-$pq->execute(null, null, null, null, null, null, null, '06:06:06', null);
-$pq->execute(null, null, null, null, null, null, null, AnewtDateTime::now(), null);
-$pq->execute(null, null, null, null, null, null, null, AnewtDateTime::sql_time(AnewtDateTime::now()), null);
-//$pq->execute(null, null, null, null, null, null, null, 'foo', null);
-//$pq->execute(null, null, null, null, null, null, null, true, null);
-//$pq->execute(null, null, null, null, null, null, null, 2, null);
-
-/* Test raw */
-$pq->execute(null, null, null, null, null, null, null, null, '"?int?"');
-
-/* Test all at once */
-$pq->execute(true, 3, 2.0, 'Test', '2006-06-06', '2006-06-06 06:06:06', '2006-06-06 06:06:06', '06:06:06', '"?raw?"');
-
-
-/* test named placeholders with associative arrays */
-$pq = $db->prepare('INSERT INTO typetesttable VALUES ( ?bool:bool_var?, ?int:int_var?, ?float:float_var?, ?string:string_var?, ?date:date_var?, ?datetime:datetime_var?, ?timestamp:timestamp_var?, ?time:time_var?, ?raw:raw_var?)');
-
-$values = array(
-	'bool_var' => null,
-	'int_var' => null,
-	'float_var' => null,
-	'string_var' => null,
-	'date_var' => null,
-	'datetime_var' => null,
-	'timestamp_var' => null,
-	'time_var' => null,
-	'raw_var' => null
-);
-
-/* Test null */
-$pq->execute($values);
-
-#/* Test booleans */
-$values['bool_var'] = true;
-$pq->execute($values);
-$values['bool_var'] = false;
-$pq->execute($values);
-
-$values['bool_var'] = null;
-
-#/* Test ints */
-$values['int_var'] = 2;
-$pq->execute($values);
-$values['int_var'] = '3';
-$pq->execute($values);
-$values['int_var'] = null;
-
-/* Test floats */
-$values['float_var'] = 2.0;
-$pq->execute($values);
-$values['float_var'] = 1.234;
-$pq->execute($values);
-$values['float_var'] = 3;
-$pq->execute($values);
-$values['float_var'] = null;
-
-
-/* Test strings */
-//class StringWrap { function render() {return 'test';} }
-$values['string_var'] = 'Test';
-$pq->execute($values);
-$values['string_var'] = 'Te\';st';
-$pq->execute($values);
-$values['string_var'] = "\t\n;--'";
-$pq->execute($values);
-$values['string_var'] = 2;
-$pq->execute($values);
-$values['string_var'] = new StringWrap();
-$pq->execute($values);
-$values['string_var'] = null;
-
-/* Test dates */
-$values['date_var'] = '2006-06-06';
-$pq->execute($values);
-$values['date_var'] = AnewtDateTime::now();
-$pq->execute($values);
-$values['date_var'] = null;
-
-/* Test datetimes */
-$values['datetime_var'] = '2006-06-06 06:06:06';
-$pq->execute($values);
-$values['datetime_var'] = AnewtDateTime::now();
-$pq->execute($values);
-$values['datetime_var'] = AnewtDateTime::sql(AnewtDateTime::now());
-$pq->execute($values);
-$values['datetime_var'] = null;
-
-/* Test timestamps */
-$values['timestamp_var'] = '2006-06-06 06:06:06';
-$pq->execute($values);
-$values['timestamp_var'] = AnewtDateTime::now();
-$pq->execute($values);
-$values['timestamp_var'] = AnewtDateTime::sql(AnewtDateTime::now());
-$pq->execute($values);
-$values['timestamp_var'] = null;
-
-/* Test times */
-$values['time_var'] = '06:06:06';
-$pq->execute($values);
-$values['time_var'] = AnewtDateTime::now();
-$pq->execute($values);
-$values['time_var'] = null;
-
-/* Test raw */
-$values['raw_var'] = '"?int?"';
-$pq->execute($values);
-$values['raw_var'] = null;
-
-/* Test all at once */
-$values = array(
-	'bool_var' => true,
-	'int_var' => 3,
-	'float_var' => 2.0,
-	'string_var' => 'Test',
-	'date_var' => '2006-06-06',
-	'datetime_var' => '2006-06-06 06:06:06',
-	'timestamp_var' => '2006-06-06 06:06:06',
-	'time_var' => '06:06:06',
-	'raw_var' => '"?raw?"'
-);
-$pq->execute($values);
-
-/* test named placeholders with containers */
-$values = new Container(array(
-	'bool_var' => null,
-	'int_var' => null,
-	'float_var' => null,
-	'string_var' => null,
-	'date_var' => null,
-	'datetime_var' => null,
-	'timestamp_var' => null,
-	'time_var' => null,
-	'raw_var' => null
-));
-
-/* Test null */
-$pq->execute($values);
-
-#/* Test booleans */
-$values->set('bool_var', true);
-$pq->execute($values);
-$values->set('bool_var', false);
-$pq->execute($values);
-
-$values->set('bool_var', null);
-
-#/* Test ints */
-$values->set('int_var', 2);
-$pq->execute($values);
-$values->set('int_var', '3');
-$pq->execute($values);
-$values->set('int_var', null);
-
-/* Test floats */
-$values->set('float_var', 2.0);
-$pq->execute($values);
-$values->set('float_var', 1.234);
-$pq->execute($values);
-$values->set('float_var', 3);
-$pq->execute($values);
-$values->set('float_var', null);
-
-
-/* Test strings */
-//class StringWrap { function render() {return 'test';} }
-$values->set('string_var', 'Test');
-$pq->execute($values);
-$values->set('string_var', 'Te\';st');
-$pq->execute($values);
-$values->set('string_var', "\t\n;--'");
-$pq->execute($values);
-$values->set('string_var', 2);
-$pq->execute($values);
-$values->set('string_var', new StringWrap());
-$pq->execute($values);
-$values->set('string_var', null);
-
-/* Test dates */
-$values->set('date_var', '2006-06-06');
-$pq->execute($values);
-$values->set('date_var', AnewtDateTime::now());
-$pq->execute($values);
-$values->set('date_var', null);
-
-/* Test datetimes */
-$values->set('datetime_var', '2006-06-06 06:06:06');
-$pq->execute($values);
-$values->set('datetime_var', AnewtDateTime::now());
-$pq->execute($values);
-$values->set('datetime_var', AnewtDateTime::sql(AnewtDateTime::now()));
-$pq->execute($values);
-$values->set('datetime_var', null);
-
-/* Test timestamps */
-$values->set('timestamp_var', '2006-06-06 06:06:06');
-$pq->execute($values);
-$values->set('timestamp_var', AnewtDateTime::now());
-$pq->execute($values);
-$values->set('timestamp_var', AnewtDateTime::sql(AnewtDateTime::now()));
-$pq->execute($values);
-$values->set('timestamp_var', null);
-
-/* Test times */
-$values->set('time_var', '06:06:06');
-$pq->execute($values);
-$values->set('time_var', AnewtDateTime::now());
-$pq->execute($values);
-$values->set('time_var', null);
-
-/* Test raw */
-$values->set('raw_var', '"?int?"');
-$pq->execute($values);
-$values->set('raw_var', null);
-
-/* Test all at once */
-$values->seed(array(
-	'bool_var' => true,
-	'int_var' => 3,
-	'float_var' => 2.0,
-	'string_var' => 'Test',
-	'date_var' => '2006-06-06',
-	'datetime_var' => '2006-06-06 06:06:06',
-	'timestamp_var' => '2006-06-06 06:06:06',
-	'time_var' => '06:06:06',
-	'raw_var' => '"?raw?"'
-));
-$pq->execute($values);
-$db->transaction_commit();
-
-/* TODO: test column and table types */
-
-$db->disconnect();
-
-?>

=== removed file 'database.old/main.lib.php'
--- database.old/main.lib.php	2006-05-16 07:08:18 +0000
+++ database.old/main.lib.php	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004  Wouter Bolsterlee <uws@xxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/database');
-
-?>

=== removed file 'database.old/module.doc.xml'
--- database.old/module.doc.xml	2008-04-20 14:01:47 +0000
+++ database.old/module.doc.xml	1970-01-01 00:00:00 +0000
@@ -1,595 +0,0 @@
-<anewt:module
-	xmlns:anewt="http://anewt.net/ns/2008/04/documentation";
-	id="database"
-	>
-
-	<anewt:title>Database module</anewt:title>
-
-	<p>The database module provides a convenient way to communicate
-		with databases. Key features are a convenient <strong>object
-			oriented API</strong>, <strong>full data type safety and
-			validation</strong>, and <strong>support for multiple database
-			engines</strong>.</p>
-
-	<p>The database module provides you with a consistent API that abstracts
-		the engine-specific functions in PHP, while retaining the full power the
-		individual database engines have to offer.</p>
-
-	<p>This chapter explains the basic concepts and contains some
-		examples to help you getting started. Refer to the API documentation
-		for a more in-depth description of the available objects and
-		methods.</p>
-
-
-	<anewt:section>
-		
-		<anewt:title>Database support</anewt:title>
-
-		<p>Anewt's database module can communicate with several database
-			engines. Anewt currently supports the following databases:</p>
-
-		<ul>
-			<li>MySQL</li>
-			<li>PostgreSQL</li>
-			<li>MS SQL Server</li>
-			<li>SQLite</li>
-		</ul>
-
-		<p>The database module uses a pluggable backend architecture to support
-			different database engines. All database specific functionality is
-			implemented in these backends. This not only includes the raw API calls
-			like <anewt:functionname>mysql_query()</anewt:functionname> and
-			<anewt:functionname>pg_fetch_assoc()</anewt:functionname>, but also quoting of user supplied
-			values and type conversion of data returned by the database
-			engine.</p>
-
-		<p>In short, Anewt abstracts the boring details like connection to the
-			database, executing queries, fetching resulting data and checking data
-			types, but Anewt will never try to be smart with the SQL you provide. It
-			also won't hide custom or specific database functionality your database
-			offers. Relational databases are just too complex and too powerful to be
-			wrapped in a simple abstraction layer.</p>
-
-		<p>You may argue that, given the maturity and standarization of the SQL
-			language, switching to another database engine is a trivial task. While
-			it may look reasonable at first sight, database portability is not to be
-			taken lightly. Most databases have very specific functionality that
-			cannot easily be ported to other databases. Just changing the connection
-			parameters is not enough to switch to another database engine! Support
-			for foreign key constraints, subqueries, triggers, views, indices and
-			sequences differs drastically between databases. Last but not least all
-			major database engines support many non-portable SQL functions and data
-			types. Not using the power your database offers is naive at best and just
-			plain stupid for real world applications. Therefore the Anewt database
-			module won't try to be smart about things the programmer knows
-			better.</p>
-
-	</anewt:section>
-
-
-	<anewt:section>
-		
-		<anewt:title>Initialization</anewt:title>
-
-		<p>First of all you will need to establish a connection to the
-			database. You are likely to do this from a initialization file
-			that you include in each file of your project. For maximum
-			flexibility you can keep the <code>$db_settings</code>
-			connection parameters in a separate config file. This is useful
-			for version control and deployment, allowing you to use different
-			settings for each machine your applications runs on. Note that the
-			<code>$db_settings</code> variable is deleted after the
-			connection has been made. This is not really needed, but a good
-			idea since it makes sure your database password can never be
-			accessed from other parts of your code.</p>
-			
-		<p>An example initialization may look like this:</p>
-
-		<anewt:example src="database-initialization">
-			<anewt:title>Initializing the database module</anewt:title>
-		</anewt:example>
-
-		<p>The first line load the database module, the following lines
-			construct a new <anewt:classref>DB</anewt:classref> instance that connects
-			to the database engine.</p>
-
-		<p>If you want to use a singleton database instance (see the
-			section about object oriented applications below), the
-			initialization step looks like this:</p>
-
-		<anewt:example src="database-initialization-singleton">
-			<anewt:title>Initializing a singleton database
-				instance</anewt:title>
-		</anewt:example>
-
-
-	</anewt:section>
-
-
-	<anewt:section>
-		
-		<anewt:title>Interacting with the database</anewt:title>
-
-		<p>Now that we have established a connection, we can retrieve
-			data from the database. To accomplish  this, we prepare a query
-			and execute it. The data from the rows in the result set are
-			simply printed. More information about prepared queries and result
-			sets can be found in the next section.</p>
-
-		<anewt:example src="database-simple-1">
-			<anewt:title>Simple data retrieval</anewt:title>
-		</anewt:example>
-
-		<p>Prepared queries support special placeholder markers that can
-			later be filled in with user data. You need to provide the data
-			type for the value that will be substituted for the placeholder.
-			Anewt takes care of all data validation and quoting, so you don't
-			need to fiddle with functions like
-			<anewt:functionname>addslashes()</anewt:functionname>
-			or <anewt:functionname>mysql_escape_string()</anewt:functionname> to make your queries
-			correct.</p>
-
-		<anewt:example src="database-simple-2">
-			<anewt:title>Providing query parameters</anewt:title>
-		</anewt:example>
-
-		<p> Anewt knows how to deal with many other data types. Read on
-			to the section on type safety for more information. </p>
-
-		<p>To retrieve the number of rows in a resultset, use the
-			<anewt:functionref>count()</anewt:functionref> method on a
-			<anewt:classref>ResultSet</anewt:classref> instance. To see how many rows
-			are affected by a query, use
-			<anewt:functionref>count_affected()</anewt:functionref>
-			(if supported by the backend).</p>
-
-		<anewt:example src="database-count">
-			<anewt:title>Getting the number of result rows</anewt:title>
-		</anewt:example>
-
-	</anewt:section>
-
-
-	<anewt:section>
-		
-		<anewt:title>Prepared queries and result sets</anewt:title>
-
-		<p>As you might have seen in the examples above, Anewt uses these steps
-			to fetch data from the database:</p>
-
-		<ul>
-			<li>Prepare a query using placeholders</li>
-			<li>Execute the query, providing parameters for the
-				placeholders</li>
-			<li>Retrieve the resulting records</li>
-		</ul>
-
-		<p>The Anewt database module contains a couple of classes:
-			<anewt:classref>DB</anewt:classref>,
-			<anewt:classref>PreparedQuery</anewt:classref>,
-			<anewt:classref>ResultSet</anewt:classref>, and
-			<anewt:classref>SQLTemplate</anewt:classref>. A
-			<anewt:classref>DB</anewt:classref>
-			instance represents a database connection. It takes care of the
-			initial connection setup phase and provides you with the
-			<anewt:functionref>prepare()</anewt:functionref> method that allows you to create a
-			new <anewt:classref>PreparedQuery</anewt:classref> instance. You should
-			never create a <anewt:classref>PreparedQuery</anewt:classref> instance by
-			directly calling its constructor: always use the
-			<code>$db->prepare()</code> method! This is needed because
-			prepared queries are tightly linked to the database connection and
-			should be setup carefully to use the correct quoting and execution
-			functions. Finally, the
-			<anewt:classref>SQLTemplate</anewt:classref> class
-			takes care of variable checking and placeholder substitution. Most
-			likely you won't have to deal with this class directly. Instead
-			you'll use the type safety it provides using the
-			<anewt:classref>PreparedQuery</anewt:classref> class.</p>
-
-		<p><anewt:classref>PreparedQuery</anewt:classref> instances can be executed by
-			calling their <code>execute()</code> method. To execute the actual SQL
-			query, you should provide valid values for the placeholders (if any). You
-			can provide multiple parameters to the <code>execute</code> method, or
-			you can provide a single array holding the values. Which method
-			you should use depends on your code. The result is exactly the
-			same.</p>
-
-		<anewt:example src="database-prepared-query">
-			<anewt:title>Executing a prepared query with
-				parameters</anewt:title>
-		</anewt:example>
-
-		<p>The result of a <code>$pq->execute()</code> is a
-			<anewt:classref>ResultSet</anewt:classref> instance. This object is used to
-			retrieve the resulting rows. Note that only certain types of SQL
-			queries may return a <anewt:classref>ResultSet</anewt:classref>
-			(<code>SELECT</code> queries do, <code>UPDATE</code> queries
-			don't). Fetching the row data can be done using these three
-			functions:</p>
-
-		<ul>
-			<li><anewt:functionref>fetch()</anewt:functionref> returns one single row from
-				the set</li>
-			<li><anewt:functionref>fetch_all()</anewt:functionref> returns all rows in the
-				set as an array</li>
-			<li><anewt:functionref>fetch_many($howmany)</anewt:functionref> returns an array
-				of <code>$howmany</code> rows</li>
-		</ul>
-
-		<p>The actual rows are associative arrays with the column name
-			(or alias) as the key and the actual data as the value. Anewt does
-			not support numeric arrays or numeric indices for result rows.
-			This is deliberate since it encourages you to write unmaintainable
-			and non-verbose code, so please don't ask for it.</p>
-
-	</anewt:section>
-
-	<anewt:section>
-		
-		<anewt:title>Type safety</anewt:title>
-
-		<p>One of the strengths of the Anewt database module is
-			<strong>type safety</strong>. This means that every variable
-			related to the database, both input and output, has an explicit
-			type. Although beginning programmers might think explicit types
-			cause more frustration than it's worth, Anewt forces you take the
-			safe route and makes sure SQL security is not something to take
-			care of when it's too late. You'll learn to appreciate it,
-			really.</p>
-
-		<p>First of all, some background information. PHP supports
-			<strong>type juggling</strong> (automatic conversion between
-			types), but this often yields unpredictable and unwanted results.
-			An example is the automatic conversion of a string to the integer
-			value 0 if it's used in an integer context. That means that
-			<code>'some text' + 5</code> results in the integer value
-			<code>5</code> instead of an error stating that strings and
-			numbers cannot be added together. Another example: <code>min('some
-			text', 5, true)</code> yields the string <code>'some
-			text'</code>. This is extremely non-obvious, given the
-			different types of the operands passed to the
-			<anewt:functionname>min()</anewt:functionname> function. When variables are silently
-			converted to other types, programming mistakes can slip in
-			unnoticed. This may cause an invalid state in your databases, or
-			even cause your application to be compromised by malicious users,
-			because a corrupted data model may cause unexpected
-			results.</p>
-
-		<p>The above code snippets show that implicit variable conversion
-			can lead to unpredictable and therefore possibly unsafe
-			applications. A second problem that needs to be tackled in a
-			database application is: how to deal with user supplied input? A
-			commonly known vulnerability that takes advantage of unsafe user
-			input handling is called <strong>SQL injection</strong>. This
-			problem is caused by unsufficient user input sanitizing and
-			escaping, causing malformed queries to be executed. Those
-			malformed queries can do harmful things, like bypass login
-			mechanisms, steal data or corrupt the database.</p>
-		
-		<p>Building SQL queries from user input can be done in a couple
-			of ways, of which <strong>variable substitution</strong> and
-			<strong>string concatenation</strong> are the most obvious.
-			Although variable substitution makes your code look
-			straight-forward and easy to read, it introduces huge security
-			problems caused by the lack of variable escaping. With string
-			concatenation, it's possible to escape values by adding function
-			calls around each variable, but this is error-prone (you're likely
-			to forget this at least once in your program) and makes it
-			impossible to reuse queries. String concatenation also leads to an
-			unreadable mess of quotes, dots and spaces.</p>
-
-		<anewt:warning>
-			
-			<p>Never use <strong>variable substitution</strong> or
-				<strong>string concatenation</strong> to include user input or
-				other variables in your SQL strings.</p>
-		
-		</anewt:warning>
-
-		<p>This document won't go into details about the ways in which
-			SQL injection and other SQL vulnerabilities can cause your
-			application to be compromised. We just show two examples below of
-			the techniques to avoid:</p>
-			
-		<anewt:example src="database-incorrect">
-			<anewt:title>Incorrect ways to construct SQL queries</anewt:title>
-		</anewt:example>
-
-		<p>To overcome the problems outlined above, the Anewt database
-			module requires you to specify placeholders with explicit data
-			types for all the values in SQL queries. All SQL strings sent to
-			the database must pass a mandatory type checking phase,
-			implemented in the <anewt:classref>SQLTemplate</anewt:classref> class. When
-			preparing a query to be executed, special placeholders mark the
-			places where your variables will be filled in. Each placeholder
-			looks like <code>?type?</code>, where the type can be one of
-			the data types from the listing below:</p>
-
-		<dl>
-
-				<dt><code>bool</code></dt>
-				<dt><code>boolean</code></dt>
-				<dd>
-						for boolean values
-						(<code>true</code> or <code>false</code>)
-				</dd>
-
-				<dt><code>i</code></dt>
-				<dt><code>int</code></dt>
-				<dt><code>integer</code></dt>
-				<dd>
-						for integer numbers
-						(eg. <code>12345</code> or <code>-10133</code>)
-				</dd>
-
-				<dt><code>f</code></dt>
-				<dt><code>float</code></dt>
-				<dt><code>double</code></dt>
-				<dd>
-						for floating point numbers
-						(eg. <code>1.41</code> or <code>3.14</code>)
-				</dd>
-
-				<dt><code>s</code></dt>
-				<dt><code>str</code></dt>
-				<dt><code>string</code></dt>
-				<dt><code>varchar</code></dt>
-				<dd>
-						for strings
-						(eg. <code>John Doe</code> or <code>"Quotes" ain't
-							funny</code>)
-				</dd>
-
-				<dt><code>date</code></dt>
-				<dt><code>datetime</code></dt>
-				<dt><code>time</code></dt>
-				<dt><code>timestamp</code></dt>
-				<dd>
-						for date and time values
-						(strings like <code>2006-03-14</code> or
-						<code>1983-01-15 18:30:00</code>, but preferabely
-						<anewt:classref>DateTimeAtom</anewt:classref> instances)
-				</dd>
-
-		</dl>
-
-		<p>If the type check fails, an error is thrown and
-			<strong>script execution immediately stops</strong>. Yes,
-			Anewt is extremely strict about this: incorrect placeholder values
-			will not pass through unnoticed, since the cause of the failed
-			check is either a programming error or a malicious user trying to
-			do nasty things. This means that you, as the programmer, have to
-			make sure each variable is of the correct type before trying to
-			substitute it into the SQL query template.</p>
-
-		<anewt:example src="database-invalid-values">
-			<anewt:title>Supplying invalid SQL values</anewt:title>
-		</anewt:example>
-
-		<p>Most placeholder types accept PHP strings as values for
-			non-string placeholders, in addition to the corresponding native
-			PHP type. For instance, if you supply the string
-			<code>'12'</code> for an integer placeholder, the string
-			will converted to a number and the result will be the same as if
-			you supplied the integer value <code>12</code>. Note that
-			this totally different from PHP's own implicit type juggling: it
-			only works if your string looks likes the expected type! So, if
-			you supply <code>'John'</code> for an integer placeholder, a
-			fatal error occurs, whereas casting to an integer in PHP would
-			cause the string to be converted to the integer value
-			<code>0</code>, which is not what you want.</p>
-
-		<anewt:example src="database-string-conversion">
-			<anewt:title>Supplying string values for non-string
-				placeholders</anewt:title>
-		</anewt:example>
-
-		<p>In addition to the types outline above, three additional data
-			types are supported. However, you should not use those for
-			user-supplied data. Only use them for your own internal purposes.
-			Dynamically named table and column names are generally not a good
-			idea, unless you really know what you're doing. You're even less
-			likely to need raw values. The values supplied are substituted in
-			the query template without any checks applied, bypassing all
-			security precautions.</p>
-
-		<dl>
-
-				<dt><code>col</code></dt>
-				<dt><code>column</code></dt>
-				<dd>
-						for column names
-						(string values, just some basic escaping done)
-				</dd>
-
-				<dt><code>table</code></dt>
-				<dd>
-						for table names
-						(string values, just some basic escaping done)
-				</dd>
-
-				<dt><code>r</code></dt>
-				<dt><code>raw</code></dt>
-				<dd>
-						for literal values
-						(any value, no checking or escaping)
-				</dd>
-
-		</dl>
-
-		<anewt:warning>
-			
-			<p><strong>Never use <code>raw</code> for user-supplied
-					data.</strong> If you do use it for user data, this has the
-				same effect as not having input checking at all, thus leaving
-				your application vulnerable for SQL exploits. Use with extreme
-				care!</p>
-		
-		</anewt:warning>
-
-		<p>In most cases, the type checking and query validation will be
-			done for you by the <anewt:classref>PreparedQuery</anewt:classref> class.
-			However, if you're building complex queries or doing other SQL
-			magic, you can use <anewt:classref>SQLTemplate</anewt:classref> directly.
-			Using this class without a
-			<anewt:classref>PreparedQuery</anewt:classref>
-			instance allows you to do variable escaping using the placeholder
-			syntax outlined above without actually issuing the query to the
-			database engine. Usage of
-			<anewt:classref>SQLTemplate</anewt:classref> is
-			pretty straight-forward, but since this is an advanced topic, this
-			manual won't go into detail about it. Look at the API
-			documentation for the exact usage. The
-			<anewt:classref>AutoRecord</anewt:classref> source code also provides lots
-			of examples to learn from.</p>
-
-	</anewt:section>
-
-
-	<anewt:section>
-		
-		<anewt:title>Type conversion</anewt:title>
-
-		<p>Now that you know all about database input and data  types,
-			it's time to look into <strong>database output</strong>.
-			Values in resulting rows from a query are automatically casted to
-			an appropriate PHP type. For most simple types the conversion is
-			pretty straightforward: <code>VARCHAR</code> columns become
-			strings, <code>INT</code> columns become PHP integers. Guess
-			how <code>FLOAT</code> and <code>BOOLEAN</code>
-			(PostgreSQL) columns end up. Exactly. All unsupported column types
-			are just the strings as returned by the lower level database
-			specific row fetching functions.. </p>
-
-		<p>A special case are date and time columns. Those are converted
-			to <anewt:classref>DateTimeAtom</anewt:classref> instances (simple objects
-			that represent a timestamp). The
-			<anewt:classref>DateTime</anewt:classref>
-			class provides static methods format these objects into strings.
-			Simple example: <code>print DateTime::date($row['last_modification'])</code>.
-			Read the chapter about the <code>DateTime</code> module for
-			more information on how to handle dates and times.</p>
-
-		<anewt:note>
-			
-			<p>Not all database backends support automatic type conversion.
-				PostgreSQL and MySQL do, but SQLite does not (it has no concept
-				of column types). Unsupported types are always strings, so for
-				unsupported database engines all row values are strings.</p>
-		
-		</anewt:note>
-
-	</anewt:section>
-
-	<anewt:section>
-		
-		<anewt:title>Convenience methods</anewt:title>
-
-		<p>The three steps required to fetch data from a database table
-			(prepare, execute, fetch) allow for maximum flexibility. However,
-			most of the time you don't need this flexibility, but just want to
-			get some data without too much hassle. To overcome this, three
-			convenience methods are provided for the three most common cases.
-			You don't have to use these methods, but for the simple cases it
-			makes your code shorter and a bit easier to read.</p>
-
-		<p>The first one is
-			<anewt:functionref>prepare_execute_fetch()</anewt:functionref>.
-			It allows you to quickly fetch a single row from the database. The
-			second one is
-			<anewt:functionref>prepare_execute_fetch_all()</anewt:functionref>,
-			which allows you to fetch all rows returned by a given query. The
-			last one is <anewt:functionref>prepare_execute()</anewt:functionref>, which is
-			useful for queries not returing result rows, eg. insert or update
-			queries.</p>
-
-		<p>All three convenience methods accept multiple parameters. The
-			first one is the SQL template, all following values are the values
-			used for parameter substitution.</p>
-
-		<anewt:example src="database-convenience">
-			<anewt:title>Database convenience methods</anewt:title>
-		</anewt:example>
-
-		<p>See the API documentation for more information about these
-			methods.</p>
-
-	</anewt:section>
-
-	<anewt:section>
-		
-		<anewt:title>Databases in object-oriented applications</anewt:title>
-
-		<p>Although Anewt supports more than one simultaneous connection
-			(just instantiate multiple <anewt:classref>DB</anewt:classref> objects),
-			most applications only use one database connection. If you're
-			building an application the object-oriented way (objects with
-			application logic and such) and your objects need to access the
-			database, you have to make the <anewt:classref>DB</anewt:classref> instance
-			available to these objects. Several solutions are possible:</p>
-
-		<p>The first solution is to <strong>pass a reference</strong>
-			to the database instance to each instance of your class and store
-			it in the instance.</p>
-
-		<anewt:example src="database-passing-instance">
-			<anewt:title>Passing the database instance as a
-				parameter</anewt:title>
-		</anewt:example>
-
-		<p>The second solution is to use a <strong>global database
-				instance</strong>. Using global variables is generally not a
-			good idea.</p>
-
-		<anewt:example src="database-global-instance">
-			<anewt:title>Using a global database instance</anewt:title>
-		</anewt:example>
-
-		<p>The third and most elegant solution is to use the
-			<strong>singleton design pattern</strong> and treat the
-			database instance as a singleton object. The PHP language is a bit
-			limited (although it's gotten slightly better in PHP5), so we have
-			to do some tricks to make it work. First of all, the database
-			initialization step has to be changed. Instead of creating a new
-			instance by using the <anewt:classref>DB</anewt:classref> constructor, we
-			use the static class method <anewt:functionref>&amp;DB::get_instance($type,
-				$settings)</anewt:functionref> to setup the database connection. You do
-			this just once; each subsequent call to the
-			<anewt:functionref>&amp;DB::get_instance()</anewt:functionref> method should have no
-			parameters. See the section about initialization for more
-			information about initializing a database.</p>
-
-		<anewt:example src="database-singleton">
-			<anewt:title>Using a singleton database instance</anewt:title>
-		</anewt:example>
-
-		<p>As you can see, you just use <code>$db =
-				&amp;DB::get_instance()</code> whenever you need the database
-			object anywhere in your code.</p>
-
-	</anewt:section>
-
-	<anewt:section>
-		
-		<anewt:title>Transactions</anewt:title>
-
-		<p>The <anewt:classref>DB</anewt:classref> class provides three simple
-			methods to begin, commit or rollback a transaction:</p>
-
-		<ul>
-			<li><anewt:functionref>DB::transaction_begin()</anewt:functionref></li>
-			<li><anewt:functionref>DB::transaction_commit()</anewt:functionref></li>
-			<li><anewt:functionref>DB::transaction_rollback()</anewt:functionref></li>
-		</ul>
-
-		<p>Note that transaction support depends on the database you're
-			using. PostgreSQL supports transactions by default, but MySQL does
-			not (at least not in all versions). Don't rely on the above
-			methods if you're not sure whether your database supports
-			them.</p>
-	
-	</anewt:section>
-
-</anewt:module>
-
-<!-- vim: set tw=72 : -->

=== removed directory 'database.old/mssql'
=== removed file 'database.old/mssql/backend.lib.php'
--- database.old/mssql/backend.lib.php	2008-10-25 22:18:29 +0000
+++ database.old/mssql/backend.lib.php	1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2005  Daniel de Jong <djong@xxxxxxxx>
- * Copyright (C) 2006  Marijn Kruisselbrink <m.kruisselbrink@xxxxxxxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/mssql/resultset');
-
-
-/**
- * MS SQL database abstraction.
- */
-class MssqlDB extends DatabaseBackend {
-
-	var $id;  /**< \private The mysql connection id */
-
-	/**
-	 * Connects to the MSSQL database.
-	 *
-	 * \param $settings
-	 *   An associative array with connection settings: the 'hostname',
-	 *   'username' and 'password' indices will be used.
-	 */
-	function connect(array $settings) {
-		is_array($settings) && isset($settings['hostname'],
-				$settings['username'], $settings['password'])
-			or trigger_error('Invalid parameters to connect()', E_USER_ERROR);
-
-		$this->id = &mssql_pconnect(
-				$settings['hostname'],
-				$settings['username'],
-				$settings['password'])
-			or trigger_error(sprintf('Could not connect to databaseserver (%s)',
-						$settings['hostname']), E_USER_ERROR);
-
-		// suppress warnings
-		if (function_exists('mssql_min_client_severity')) mssql_min_client_severity(100);
-		if (function_exists('mssql_min_server_severity')) mssql_min_server_severity(100);
-		if (function_exists('mssql_min_message_severity')) mssql_min_message_severity(100);
-		if (function_exists('mssql_min_error_severity')) mssql_min_error_severity(100);
-
-	}
-
-	/**
-	 * Disconnects from the MSSQL database.
-	 */
-	function disconnect() {
-		mssql_close($this->id);
-	}
-
-	/**
-	 * Selects the given database.
-	 *
-	 * \param $name
-	 *   The name of the database to use.
-	 */
-	function select_db($name) {
-		assert('is_string($name)');
-
-		mssql_select_db($name, $this->id) or trigger_error('Could not select database', E_USER_ERROR);
-	}
-
-	/**
-	 * Returns the type of this database backend.
-	 *
-	 * \return
-	 *   Always returns the string 'mssql'.
-	 */
-	function get_type() {
-		return 'mssql';
-	}
-
-	/**
-	 * Escapes a string for SQL queries.
-	 *
-	 * \param $str
-	 *   The string to escape.
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function escape_string($str) {
-		if (is_null($str))
-			return 'NULL';
-
-		return "'" . str_replace("'", "''", $str) . "'";
-	}
-}
-
-?>

=== removed file 'database.old/mssql/resultset.lib.php'
--- database.old/mssql/resultset.lib.php	2009-02-16 14:26:27 +0000
+++ database.old/mssql/resultset.lib.php	1970-01-01 00:00:00 +0000
@@ -1,96 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2004  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2005  Daniel de Jong <djong@xxxxxxxx>
- * Copyright (C) 2006  Marijn Kruisselbrink <m.kruisselbrink@xxxxxxxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-define(ANEWT_DATABASE_MSSQL_ROWS_AFFECTED_EXISTS, function_exists('mssql_rows_affected'));
-
-
-/**
- * MS SQL-specific database result set.
- */
-class MssqlResultSet extends ResultSet {
-
-	var $backend; /**< \private The backend instance */
-	var $rs;      /**< \private A resultset instance */
-	var $rowcount;/**< \private The number of affected rows (for update/insert/delete queries) */
-	
-	/**
-	 * Constructs a new MssqlResultSet.
-	 *
-	 * \param $sql
-	 *   The sql query to execute.
-	 * \param $backend
-	 *   A reference to the used backend.
-	 */
-	function MssqlResultSet($sql, &$backend) {
-		assert('is_string($sql)');
-
-		$this->sql = $sql;
-  		$this->backend = &$backend;
-
-		// Attention! Due to a bug in the mssql driver, when you use insert or
-		// update, mssql_query() always returns false, so that error checking is
-		// effectively impossible.
-		$this->rs = mssql_query($sql, $this->backend->id);
-		
-		if (!ANEWT_DATABASE_MSSQL_ROWS_AFFECTED_EXISTS) {
-			// For update/insert/delete queries, figure out the number of rows affected
-			$kw = strtolower(substr(trim($sql), 0, 6));
-			if ($kw == "delete" || $kw == "insert" || $kw == "update") {
-				$rs = mssql_query("SELECT @@ROWCOUNT", $this->backend->id);
-				list($this->rowcount) = mssql_fetch_row($rs);
-			} else {
-				$this->rowcount = 0;
-			}
-		}
-	}
-
-	function fetch() {
-		// Attention! Due to a bug in the sybase driver, a boolean 'true' is
-		// returned when the query was succesful but did not return any rows. We
-		// work around this problem by checking for this 'true' value.
-		if ($this->rs === true) {
-			return false;
-		}
-		return mssql_fetch_assoc($this->rs);
-	}
-
-	function count() {
-		// Attention! See notes above.
-		if ($this->rs === true) {
-			return 0;
-		}
-		return mssql_num_rows($this->rs);
-	}
-
-	function count_affected() {
-		if (ANEWT_DATABASE_MSSQL_ROWS_AFFECTED_EXISTS) {
-			return mssql_rows_affected($this->rs);
-		} else {
-			return $this->rowcount;
-		}
-	}
-}
-
-?>

=== removed directory 'database.old/mysql'
=== removed file 'database.old/mysql/backend.lib.php'
--- database.old/mysql/backend.lib.php	2008-11-07 11:41:40 +0000
+++ database.old/mysql/backend.lib.php	1970-01-01 00:00:00 +0000
@@ -1,166 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2004  Jasper Looije <jasper@xxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/mysql/resultset');
-
-
-/**
- * Class providing MySQL database connectivity.
- */
-class MysqlDB extends DatabaseBackend
-{
-	var $id; /**< \private The database connection id */
-
-	/**
-	 * Connects to the MySQL database.
-	 *
-	 * \param settings An associative array with connection settings: the
-	 * 'hostname', 'username' and 'password' indices will be used.
-	 */
-	function connect(array $settings)
-	{
-		is_array($settings) &&
-			isset($settings['hostname'], $settings['username'],
-					$settings['password'])
-			or trigger_error('Invalid parameters to connect()', E_USER_ERROR);
-
-		$this->id = mysql_pconnect(
-				$settings['hostname'],
-				$settings['username'],
-				$settings['password'],
-				true)
-			or trigger_error(sprintf('Could not connect to database (%d: %s)',
-						mysql_errno($this->id), mysql_error($this->id)),
-					E_USER_ERROR);
-
-		if (array_has_key($settings, 'database'))
-			$this->select_db($settings['database']);
-		
-	}
-
-	/**
-	 * Disconnects from the MySQL database.
-	 */
-	function disconnect()
-	{
-		mysql_close($this->id);
-	}
-
-	/**
-	 * Selects the given database.
-	 *
-	 * \param $name The name of the database to use.
-	 */
-	function select_db($name)
-	{
-		assert('is_string($name)');
-
-		mysql_select_db($name, $this->id) or trigger_error(sprintf('Could not select database (%d: %s)', mysql_errno($this->id), mysql_error($this->id)), E_USER_ERROR);
-	}
-
-	/**
-	 * Returns the type of this database backend.
-	 *
-	 * \return Always returns the string 'mysql'.
-	 */
-	function get_type()
-	{
-		return 'mysql';
-	}
-
-	/**
-	 * Escapes a string for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_string($str)
-	{
-		assert('is_string($str)');
-
-		/* The mysql_real_escape_string function depends on a valid connection,
-		 * so it can only be used if $this->id is a mysql resource, otherwise
-		 * mysql_escape_string has to be used. The $this->id resource is null if
-		 * the database connection is (not yet) established and SQLTemplate is
-		 * used to escape SQL strings. */
-
-		if (is_resource($this->id))
-			$str = mysql_real_escape_string($str, $this->id);
-		else
-			$str = mysql_escape_string($str);
-
-		$out = sprintf("'%s'", $str);
-		return $out;
-	}
-
-	/**
-	 * Escapes a table name for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_table_name($str)
-	{
-		assert('is_string($str)');
-
-		$parts = explode('.', $str);
-
-		if (count($parts) == 1)
-		{
-			/* Add quotes */
-			$out = sprintf('`%s`', $str);
-
-		} else {
-			/* Add quotes around each part */
-			$result = array();
-			foreach ($parts as $part)
-				$result[] = sprintf('`%s`', $part);
-
-			$out = implode('.', $result);
-		}
-
-		return $out;
-	}
-
-	/**
-	 * Escapes a column name for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_column_name($str)
-	{
-		assert('is_string($str)');
-
-		/* Same as escape_table_name */
-		$out = $this->escape_table_name($str);
-		return $out;
-	}
-
-}
-
-?>

=== removed file 'database.old/mysql/resultset.lib.php'
--- database.old/mysql/resultset.lib.php	2009-07-20 20:39:48 +0000
+++ database.old/mysql/resultset.lib.php	1970-01-01 00:00:00 +0000
@@ -1,162 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * This code is copyrighted and distributed under the terms of the GNU LGPL.
- * See the README file for more information.
- */
-
-
-/**
- * MySQL-specific database result set.
- */
-class MysqlResultSet extends ResultSet {
-
-	var $backend;              /**< \private The backend instance */
-	var $rs;                   /**< \private A resultset instance */
-	var $data_types;           /**< \private The data types in this result set */
-	var $completely_traversed; /**< \private Whether this result set has been completely traversed */
-	var $num_rows;             /**< \private Total number of rows; only valid if completely_traversed is true */
-	var $freed;                /**< \private Whether this result set has been freed */
-
-	/**
-	 * Constructs a new MysqlResultSet
-	 *
-	 * \param $sql The sql query to execute.
-	 * \param $backend A reference to the used backend.
-	 */
-	function MysqlResultSet($sql, &$backend)
-	{
-		assert('is_string($sql)');
-
-		$this->sql = $sql;
-		$this->backend = &$backend;
-
-		$this->completely_traversed = false;
-		$this->freed = false;
-
-		$this->rs = mysql_query($sql, $this->backend->id) or
-			trigger_error(sprintf('Query failed (%d: %s)',
-						mysql_errno($this->backend->id),
-						mysql_error($this->backend->id)), E_USER_ERROR);
-
-
-		/* Deduce column types for SELECT queries */
-
-		if ($this->query_type() == ANEWT_DATABASE_SQL_QUERY_TYPE_SELECT)
-			$this->deduce_types();
-	}
-
-	/**
-	 * Free resources associated with this result set.
-	 */
-	function free()
-	{
-		if (!$this->freed && is_resource($this->rs))
-			mysql_free_result($this->rs);
-
-		$this->freed = true;
-	}
-
-
-	/* Fetching results */
-
-	function fetch()
-	{
-		if ($this->completely_traversed)
-			return false;
-
-		$row = mysql_fetch_assoc($this->rs);
-
-		/* No more rows? */
-		if ($row === false)
-		{
-			$this->completely_traversed = true;
-			$this->free();
-			return false;
-		}
-
-		$this->num_rows++;
-		$this->cast_row($row);
-		return $row;
-	}
-
-
-	/* Result counting */
-
-	function count()
-	{
-		/* mysql_num_rows() fails if the result set was freed, so we return the
-		 * number of rows we fetched earlier */
-		if ($this->completely_traversed)
-			return $this->num_rows;
-
-		return mysql_num_rows($this->rs);
-	}
-
-	function count_affected()
-	{
-		return mysql_affected_rows($this->backend->id);
-	}
-
-
-	/* Type casting */
-
-	function deduce_types()
-	{
-		for ($i = 0; $i < mysql_num_fields($this->rs); $i++)
-		{
-			$name = mysql_field_name($this->rs, $i);
-			$type = mysql_field_type($this->rs, $i);
-			$this->data_types[$name] = $type;
-		}
-	}
-
-	function cast_row(&$row)
-	{
-		assert('is_assoc_array($row)');
-
-		foreach (array_keys($row) as $key)
-		{
-			$type = $this->data_types[$key];
-			$value = &$row[$key];
-
-			/* Don't cast null values */
-			if (is_null($value))
-				continue;
-
-			switch ($type)
-			{
-				case 'int':
-					$value = (int) $value;
-					break;
-
-				case 'real':
-					$value = (float) $value;
-					break;
-
-				case 'string':
-				case 'blob':
-					$value = (string) $value;
-					break;
-
-				case 'date':
-				case 'datetime':
-				case 'time':
-				case 'timestamp':
-					$value = AnewtDateTime::parse_string($value);
-					break;
-
-				default:
-					/* No conversion, leave as string */
-					break;
-			}
-
-			$row[$key] = $value;
-			unset($value);
-		}
-	}
-}
-
-?>

=== removed directory 'database.old/postgresql'
=== removed file 'database.old/postgresql/backend.lib.php'
--- database.old/postgresql/backend.lib.php	2009-03-27 15:44:13 +0000
+++ database.old/postgresql/backend.lib.php	1970-01-01 00:00:00 +0000
@@ -1,244 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/postgresql/resultset');
-
-
-/**
- * Class providing PostgreSQL database connectivity.
- */
-class PostgreSQLDB extends DatabaseBackend {
-
-	var $id;        /**< \private The database connection id */
-	var $settings;  /**< \private Database connection settings */
-
-	/**
-	 * Sets up the settings for this backend. This is used for deferred database
-	 * connections, when the settings are needed before a connection is made.
-	 * Will be overwritten by PostgreSQLDB::connect($settings).
-	 *
-	 * \see connect
-	 */
-	function setup($settings) {
-		$this->settings = $settings;
-	}
-	
-	/**
-	 * Connects to the PostgreSQL database.
-	 *
-	 * \param settings An associative array with connection settings: the
-	 * 'hostname', 'username' and 'password' indices will be used for connection
-	 * setttings. The key 'keep_settings' can be used to indicate whether the
-	 * settings are stored. The 'escape_column_names' and 'escape_table_names'
-	 * keys can be set to indicate whether column and table names should be
-	 * escaped when using CRUD functions.
-	 */
-	function connect(array $settings) {
-		if (is_null($settings))
-			$settings = array();
-
-		assert('is_assoc_array($settings)');
-
-		/* We support "hostname", "username" and "pass" too, although the
-		 * real connection string uses other names */
-		$aliases = array(
-				'hostname' => 'host',
-				'pass' => 'password',
-				'username' => 'user',
-				'database' => 'dbname',
-				);
-		foreach ($aliases as $old => $new) {
-			if (array_has_key($settings, $old)) {
-				array_set_default($settings, $new, $settings[$old]);
-			}
-		}
-
-		/* List of keywords that are allowed in the connection string: */
-		$keywords = array('host', 'hostaddr', 'port', 'dbname', 'user',
-				'password', 'connect_timeout', 'options', 'sslmode', 'service');
-
-		/* Create a connection string from the supplied values, leaving out
-		 * illegal (name, value) pairs */
-		$options = array();
-		foreach ($keywords as $keyword) {
-			if (array_key_exists($keyword, $settings)) {
-				$value = $settings[$keyword];
-
-				assert('is_string($value)');
-
-				/* Escape single and double quotes */
-				$value = str_replace("'", "\'", $value);
-				$value = str_replace('"', '\"', $value);
-
-				$options[] = sprintf('%s=%s', $keyword, $value);
-			}
-		}
-		$connection_string = implode(' ', $options);
-
-		$this->id = pg_connect($connection_string) or
-			trigger_error(sprintf('Could not connect to database %s',
-						$settings['dbname']), E_USER_ERROR);
-
-		/* Keep connection settings only if requested. This makes select_db()
-		 * work, but stores the plaintext password in the object's memory. */
-		if (!array_get_default($settings, 'keep_settings', false)) {
-			/* Unset both the aliases and the connection keywords */
-			array_unset_keys($settings, array_keys($aliases));
-			array_unset_keys($settings, $keywords);
-		}
-
-		$this->settings = $settings;
-	}
-
-	/**
-	 * Disconnects from the PostgreSQL database.
-	 */
-	function disconnect() {
-		pg_close($this->id);
-	}
-
-	/**
-	 * Selects the given database. PostgreSQL does not support run-time database
-	 * switching, so we connect again with a different dbname parameter. This
-	 * requires keep_settings to be true in the connection options passed to
-	 * connect().
-	 *
-	 * \param $name The name of the database to use.
-	 *
-	 * \see connect
-	 */
-	function select_db($name) {
-		assert('is_string($name)');
-
-		if (isset($this->settings) && is_array($this->settings)) {
-			$settings = $this->settings;
-			$settings['dbname'] = $name;
-			$this->connect($settings);
-
-		} else {
-			trigger_error('PostgreSQLDB::select_db() does not work if you
-					didn\'t set keep_settings to true in the connection
-					options.', E_USER_ERROR);
-		}
-	}
-
-	/**
-	 * Returns the type of this database backend.
-	 *
-	 * \return Always returns the string 'postgresql'.
-	 */
-	function get_type() {
-		return 'postgresql';
-	}
-
-	/**
-	 * Escapes a boolean for SQL queries.
-	 *
-	 * \param $bool The boolean to escape.
-	 *
-	 * \return The escaped value.
-	 */
-	function escape_boolean($bool) {
-		assert('is_bool($bool)');
-		return $bool ? 'true' : 'false';
-	}
-
-	/**
-	 * Escapes a string for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_string($str) {
-		assert('is_string($str)');
-		return "'" . pg_escape_string($str) . "'";
-	}
-
-	/**
-	 * \private
-	 *
-	 * Escapes a column or table name unconditionally.
-	 *
-	 * \param $str
-	 *   The string to escape
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function _escape_column_or_table_name($str) {
-		assert('is_string($str)');
-
-		$quote_char = '"';
-		$parts = explode('.', $str);
-
-		if (count($parts) === 1) {
-			/* Add quotes */
-			return $quote_char . $str . $quote_char;
-
-		} else {
-			/* Add quote only for the last part */
-			$result = array();
-			foreach ($parts as $part) {
-				$result[] = $quote_char . $part . $quote_char;
-			}
-			return implode('.', $result);
-		}
-	}
-
-	/**
-	 * Escapes a table name for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_table_name($str) {
-		assert('is_string($str)');
-
-		if (!array_get_default($this->settings, 'escape_table_names', true))
-			return $str;
-
-		return $this->_escape_column_or_table_name($str);
-	}
-
-	/**
-	 * Escapes a column name for SQL queries.
-	 *
-	 * \param $str The string to escape.
-	 *
-	 * \return The escaped string.
-	 */
-	function escape_column_name($str) {
-		assert('is_string($str)');
-
-		if (!array_get_default($this->settings, 'escape_column_names', true))
-			return $str;
-
-		return $this->_escape_column_or_table_name($str);
-	}
-
-}
-
-
-?>

=== removed file 'database.old/postgresql/resultset.lib.php'
--- database.old/postgresql/resultset.lib.php	2009-07-20 20:39:48 +0000
+++ database.old/postgresql/resultset.lib.php	1970-01-01 00:00:00 +0000
@@ -1,180 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-/**
- * PostgreSQL-specific database result set.
- */
-class PostgreSQLResultSet extends ResultSet
-{
-	var $backend;    /**< \private The backend instance */
-	var $rs;         /**< \private A resultset instance */
-	var $data_types; /**< \private The data types in this result set */
-	var $freed;      /**< \private Whether this result set has been freed */
-
-	/**
-	 * Constructs a new PostgreSQLResultSet
-	 *
-	 * \param $sql The sql query to execute.
-	 * \param $backend A reference to the used backend.
-	 */
-	function PostgreSQLResultSet($sql, &$backend)
-	{
-		assert('is_string($sql)');
-
-		$this->sql = $sql;
-		$this->backend = &$backend;
-
-		$this->freed = false;
-
-		$this->rs = pg_query($this->backend->id, $sql) or
-			trigger_error(sprintf('Query failed (%s)',
-						pg_last_error($this->backend->id)), E_USER_ERROR);
-
-
-		/* Deduce column types for SELECT queries */
-
-		if ($this->query_type() == ANEWT_DATABASE_SQL_QUERY_TYPE_SELECT)
-			$this->deduce_types();
-	}
-
-	/**
-	 * Free resources associated with this result set.
-	 */
-	function free()
-	{
-		if (!$this->freed && is_resource($this->rs))
-			pg_free_result($this->rs);
-
-		$this->freed = true;
-	}
-
-
-	function fetch()
-	{
-		$row = pg_fetch_assoc($this->rs);
-
-		/* No more rows? */
-		if ($row === false)
-		{
-			$this->free();
-			return false;
-		}
-
-		$this->cast_row($row);
-		return $row;
-	}
-
-	function count()
-	{
-		return pg_num_rows($this->rs);
-	}
-
-	function count_affected()
-	{
-		return pg_affected_rows($this->rs);
-	}
-
-	/**
-	 * \private Deduces the data types in this result set. This uses information
-	 * about the resultset as provided by the database.
-	 *
-	 * \see PostgreSQLResultSet::cast_types
-	 */
-	function deduce_types()
-	{
-		for ($i = 0; $i < pg_num_fields($this->rs); $i++)
-		{
-			$name = pg_field_name($this->rs, $i);
-			$type = pg_field_type($this->rs, $i);
-			$this->data_types[$name] = $type;
-		}
-	}
-
-	/**
-	 * \private Casts a row of data into native PHP data types. The array is
-	 * modified in-place and no result is returned.
-	 *
-	 * \param $row
-	 *   A row of data.
-	 *
-	 * \see PostgreSQLResultSet::deduce_types
-	 */
-	function cast_row(&$row)
-	{
-		assert('is_assoc_array($row)');
-
-		foreach (array_keys($row) as $key)
-		{
-			$type = $this->data_types[$key];
-			$value = $row[$key];
-
-			/* Don't cast null values */
-			if (is_null($value))
-				continue;
-
-			switch ($type)
-			{
-				case 'int2':
-				case 'int4':
-				case 'int8':
-					$value = (int) $value;
-					break;
-
-				case 'float4':
-				case 'float8':
-				case 'numeric':
-				case 'money':
-					$value = (float) $value;
-					break;
-
-				case 'varchar':
-				case 'bpchar':
-					$value = (string) $value;
-					break;
-
-				case 'bool':
-					$value = ($value === 't');
-					break;
-
-				case 'timestamp':
-				case 'date':
-				case 'time':
-				case 'datetime':
-					$value = AnewtDateTime::parse_string($value);
-					break;
-
-				case 'inet':
-					/* FIXME: What to do with these? */
-
-				default:
-					/* No conversion, leave as string */
-					break;
-			}
-
-			$row[$key] = $value;
-			unset($value);
-		}
-	}
-}
-
-?>

=== removed file 'database.old/preparedquery.lib.php'
--- database.old/preparedquery.lib.php	2009-03-27 15:48:32 +0000
+++ database.old/preparedquery.lib.php	1970-01-01 00:00:00 +0000
@@ -1,106 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2004-2005  Jasper Looije <jasper@xxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-/**
- * Prepared Query class. This class takes care of parameter checking and value
- * substitution.
- */
-class PreparedQuery {
-	var $db;                           /**< \private Database object instance reference */
-	var $sql_template;                 /**< \private SQLTemplate instance */
-	var $debug = false;                /**< Enable/disable debugging */
-	var $debug_print = false;          /**< Print queries before execution */
-
-	/**
-	 * \private Constructs a new PreparedQuery. This instance can be executed
-	 * later. Don't use this method directly: use $db->prepare() instead.
-	 *
-	 * \param $sql_template_str
-	 *   SQL query template with ?int? style placeholders.
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \see SQLTemplate
-	 */
-	function PreparedQuery($sql_template_str, &$db) {
-
-		/* Sanity checks */
-		assert('is_string($sql_template_str)');
-		assert('is_object($db)');
-
-		/* Initialize */
-		$this->db = &$db;
-		$this->sql_template = new SQLTemplate($sql_template_str, $db);
-	}
-
-
-	/**
-	 * Executes a query. This function takes a variable number of arguments or
-	 * one array parameter.
-	 *
-	 * \param $values
-	 *   One array or multiple values that will be substituted for the
-	 *   placeholders in the prepared query.
-	 *
-	 * \return
-	 *   A ResultSet instance for this query.
-	 *
-	 * \see
-	 *   SQLTemplate::fill()
-	 */
-	function &execute($values=null) {
-
-		/* Connect if that's still needed. */
-		$this->db->connect();
-		
-		/* Pass along parameters to SQLTemplate::fill() */
-		$args = func_get_args();
-		if ((count($args) == 1) && (is_array($args[0]) || $args[0] instanceof Container))
-			$args = $args[0];
-		$query = $this->sql_template->fill($args);
-
-		/* Debug mode? */
-		if ($this->debug) {
-			/* Don't keep too many queries since it may cause memory exhaustion */
-			if (count($this->db->queries_executed) > 500)
-				array_splice($this->db->queries_executed, 0, 250);
-
-			$this->db->queries_executed[] = $query;
-		}
-		if ($this->debug_print) {
-			echo $query, "\n";
-		}
-
-		$rstype = ucfirst(strtolower($this->db->backend->get_type())) . 'ResultSet';
-		$this->db->num_queries_executed++;
-		$this->db->last_query = $query;
-
-		$rs = new $rstype($query, $this->db->backend);
-		return $rs;
-	}
-
-}
-
-?>

=== removed file 'database.old/resultset.lib.php'
--- database.old/resultset.lib.php	2009-02-16 15:31:56 +0000
+++ database.old/resultset.lib.php	1970-01-01 00:00:00 +0000
@@ -1,185 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * This code is copyrighted and distributed under the terms of the GNU LGPL.
- * See the README file for more information.
- */
-
-
-/**
- * Class representing database result sets.
- *
- * Several methods are available to fetch the actual data from the database.
- */
-class ResultSet
-{
-	/**
-	 * Constructor executes the query.
-	 */
-	function ResultSet($sql, &$backend) {
-		trigger_error('ResultSet() must be overridden', E_USER_ERROR);
-	}
-
-	/**
-	 * Find out the type of the query for this ResultSet instance.
-	 *
-	 * \return
-	 *   The type of the query. These are constants like
-	 *   ANEWT_DATABASE_SQL_QUERY_TYPE_SELECT and
-	 *   ANEWT_DATABASE_SQL_QUERY_TYPE_INSERT.
-	 */
-	function query_type()
-	{
-		$first_word = preg_replace('/^([a-z]+).*$/s', '\1', strtolower(trim(substr(ltrim($this->sql), 0, 10))));
-		switch ($first_word)
-		{
-			case 'select':    return ANEWT_DATABASE_SQL_QUERY_TYPE_SELECT;
-			case 'insert':    return ANEWT_DATABASE_SQL_QUERY_TYPE_INSERT;
-			case 'replace':   return ANEWT_DATABASE_SQL_QUERY_TYPE_REPLACE;
-			case 'update':    return ANEWT_DATABASE_SQL_QUERY_TYPE_UPDATE;
-			case 'delete':    return ANEWT_DATABASE_SQL_QUERY_TYPE_DELETE;
-
-			case 'create':    return ANEWT_DATABASE_SQL_QUERY_TYPE_CREATE;
-			case 'alter':     return ANEWT_DATABASE_SQL_QUERY_TYPE_ALTER;
-			case 'drop':      return ANEWT_DATABASE_SQL_QUERY_TYPE_DROP;
-
-			case 'begin':     return ANEWT_DATABASE_SQL_QUERY_TYPE_BEGIN;
-			case 'commit':    return ANEWT_DATABASE_SQL_QUERY_TYPE_COMMIT;
-			case 'rollback':  return ANEWT_DATABASE_SQL_QUERY_TYPE_ROLLBACK;
-
-			default:          return ANEWT_DATABASE_SQL_QUERY_TYPE_UNKNOWN;
-		}
-	}
-
-	/**
-	 * Free resources associated with this result set. You cannot use any
-	 * methods on the result set instance anymore after calling this method.
-	 *
-	 * This method should be overridden using backend-specific code.
-	 */
-	function free()
-	{
-		/* Do nothing */
-	}
-
-	/* Fetching results */
-
-	/**
-	 * Returns the next row in this result set.
-	 *
-	 * \return
-	 *   An associative array containing all fields of the next result row from
-	 *   the result set.
-	 *
-	 * \see ResultSet::fetch_all
-	 * \see ResultSet::fetch_many
-	 */
-	function fetch()
-	{
-		trigger_error('ResultSet::fetch() must be overridden', E_USER_ERROR);
-	}
-
-	/**
-	 * Returns all remaining rows from the current resultset.
-	 *
-	 * \return
-	 *   A numeric array containing the result rows as associative array (may be
-	 *   an empty list).
-	 *
-	 * \see ResultSet::fetch
-	 * \see ResultSet::fetch_many
-	 */
-	function fetch_all()
-	{
-		$rows = array();
-		while ($row = $this->fetch())
-			$rows[] = $row;
-
-		return $rows;
-	}
-
-	/**
-	 * Returns the specified number of rows from the current resultset. Note
-	 * that the actual number of rows may be lower than the value specified,
-	 * since there may be less rows in the set.
-	 *
-	 * \param $num
-	 *   The number of rows to return (optional, defaults to 1).
-	 *
-	 * \return
-	 *   A numeric array containing the result rows as associative array
-	 *   (the list may contain less than $num rows, or may even be empty).
-	 *
-	 * \see ResultSet::fetch
-	 * \see ResultSet::fetch_all
-	 */
-	function fetch_many($num=1)
-	{
-		assert('is_int($num) && $num >= 1;');
-
-		$rows = array();
-		while ($num-- > 0)
-		{
-			$row = $this->fetch();
-
-			if (!$row)
-				break;
-
-			$rows[] = $row;
-		}
-		return $rows;
-	}
-
-
-	/* Result counting */
-
-	/**
-	 * Returns the number of resulting rows in this resultset. This method might
-	 * not be available for some databases (it works at least with MySQL and
-	 * PostgreSQL though).
-	 *
-	 * \return
-	 *   The total number of result rows.
-	 */
-	function count()
-	{
-		trigger_error('ResultSet::count() must be overridden', E_USER_ERROR);
-	}
-
-	/**
-	 * Returns the number of rows that where affected by the last executed
-	 * query. This method might nog be available for some databases (it works at
-	 * least with MySQL and PostgreSQL though).
-	 */
-	function count_affected()
-	{
-		trigger_error('ResultSet::count_affected() must be overridden', E_USER_ERROR);
-	}
-
-
-	/* Type casting */
-
-	/**
-	 * \private Deduces the data types in this result set. This method can be
-	 * implemented in backends to do automatic type conversion.
-	 */
-	function deduce_types()
-	{
-	}
-
-	/**
-	 * \private Casts a row of data into native PHP data types. The array is
-	 * modified in-place and no result is returned. This method can be
-	 * implemented in backend to do automatic type conversion.
-	 *
-	 * \param $row
-	 *   A row of data.
-	 */
-	function cast_row(&$row)
-	{
-	}
-}
-
-?>

=== removed directory 'database.old/sqlite'
=== removed file 'database.old/sqlite/backend.lib.php'
--- database.old/sqlite/backend.lib.php	2008-10-25 22:18:29 +0000
+++ database.old/sqlite/backend.lib.php	1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@xxxxxxxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-anewt_include('database/sqlite/resultset');
-
-
-/**
- * Class providing SQLite database connectivity.
- */
-class SqliteDB extends DatabaseBackend {
-
-	var $handle; /**< \private The database handle */
-
-	/**
-	 * Returns the type of this database backend.
-	 *
-	 * \return
-	 *   Always returns the string 'sqlite'.
-	 */
-	function get_type() {
-		return 'sqlite';
-	}
-
-	/**
-	 * Opens the SQLite database.
-	 *
-	 * \param settings An associative array with connection settings: the
-	 * 'filename' and 'mode' indices will be used (but mode is optional).
-	 */
-	function connect(array $settings) {
-		is_array($settings) && array_has_key($settings, 'filename')
-			or trigger_error('Invalid parameters to connect()', E_USER_ERROR);
-
-		$mode = array_get_default($settings, 'mode', 0666);
-		
-		$this->handle = sqlite_open(
-				$settings['filename'],
-				$mode,
-				$error)
-			or trigger_error(sprintf('Could not open database (%s)', $error),
-					E_USER_ERROR);
-	}
-
-	/**
-	 * Closes the SQLite database.
-	 */
-	function disconnect() {
-		sqlite_close($this->handle);
-	}
-
-	/**
-	 * Selects the given database. This closes the current database, and opens
-	 * the given database with a default mode of 0666 (octal).
-	 *
-	 * \param $name
-	 *   The filename of the database to use.
-	 */
-	function select_db($name) {
-		assert('is_string($name)');
-
-		disconnect();
-		connect(array('filename' => $name));
-	}
-
-	/**
-	 * Escapes a string for SQL queries.
-	 *
-	 * \param $str
-	 *   The string to escape.
-	 *
-	 * \return
-	 *   The escaped string.
-	 */
-	function escape_string($str) {
-		if (is_null($str))
-			return 'NULL';
-
-		return "'" . sqlite_escape_string($str) . "'";
-	}
-}
-
-?>

=== removed file 'database.old/sqlite/resultset.lib.php'
--- database.old/sqlite/resultset.lib.php	2007-08-01 10:01:29 +0000
+++ database.old/sqlite/resultset.lib.php	1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@xxxxxxxxxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-/**
- * Sqlite-specific database result set.
- */
-class SqliteResultSet extends ResultSet {
-
-	var $backend;        /**< \private The backend instance */
-	var $rs;             /**< \private A resultset instance */
-	var $rows_affected;  /**< \private The number of rows that was changed by this query */
-
-	/**
-	 * Constructs a new SqliteResultSet
-	 *
-	 * \param $sql
-	 *   The sql query to execute.
-	 *
-	 * \param $backend
-	 *   A reference to the used backend.
-	 */
-	function SqliteResultSet($sql, &$backend) {
-		assert('is_string($sql)');
-
-		$this->sql = $sql;
-		$this->backend = &$backend;
-
-		$this->rs = sqlite_query($this->backend->handle, $sql)
-			or trigger_error(sprintf('Query failed (%s)',
-				sqlite_error_string(sqlite_last_error($this->backend->handle))),
-				E_USER_ERROR);
-		$this->rows_affected = sqlite_changes($this->backend->handle);
-	}
-
-	function fetch() {
-		return sqlite_fetch_array($this->rs, SQLITE_ASSOC, true);
-	}
-
-	function count() {
-		return sqlite_num_rows($this->rs);
-	}
-
-	function count_affected() {
-		return $this->rows_affected;
-	}
-}
-
-?>

=== removed file 'database.old/sqlite/test.php'
--- database.old/sqlite/test.php	2006-06-04 21:15:22 +0000
+++ database.old/sqlite/test.php	1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-<?php
-
-error_reporting(E_ALL);
-require_once '../../anewt.lib.php';
-anewt_include('database');
-
-// Create a database instance
-$db = new DB('sqlite', array('filename' => ':memory:'));
-
-// Create a table and insert some test rows
-$db->prepare_execute("BEGIN");
-$db->prepare_execute("CREATE TABLE foo (a)");
-$ins = $db->prepare("INSERT INTO foo (a) VALUES (?str?)");
-$ins->execute("foo");
-$ins->execute("b\"ar");
-$db->prepare_execute("COMMIT");
-
-// Retrieve the rows from the table
-$qry = $db->prepare("SELECT * FROM foo ORDER BY a");
-$rs = $qry->execute();
-assert('is_a($rs, "SqliteResultSet")');
-assert('$rs->count() === 2');
-$rows = $rs->fetch_all();
-assert('count($rows) === 2');
-assert('is_array($rows[0])');
-assert('is_array($rows[1])');
-assert('count($rows[0]) === 1');
-assert('$rows[0]["a"] === "b\"ar"');
-
-// Test retrieving of an empty resultset
-$qry = $db->prepare("SELECT * FROM foo WHERE a <> a");
-$rs = $qry->execute();
-assert('$rs->count() === 0');
-assert('$rs->fetch() === FALSE');
-assert('$rs->fetch() === FALSE');
-$rs = $qry->execute();
-assert('$rs->fetch_all() === array()');
-
-// Test resulting resultset for an update query
-$qry = $db->prepare("UPDATE foo SET a=?str? WHERE a=?str?");
-$rs = $qry->execute('boo', 'b"ar');
-assert('$rs->count_affected() === 1');
-assert('$rs->count() === 0');
-assert('$rs->fetch() === FALSE');
-$rs = $qry->execute('boo', 'bar');
-assert('$rs->count_affected() === 0');
-
-// Test transaction methods
-$db->transaction_begin();
-$db->prepare_execute("INSERT INTO foo (a) VALUES (?str?)", "marijn");
-$db->transaction_rollback();
-assert('count($db->prepare_execute_fetch_all("SELECT * FROM foo WHERE a=?str?", "marijn")) === 0');
-
-$db->transaction_begin();
-$db->prepare_execute("INSERT INTO foo (a) VALUES (?str?)", "marijn");
-$db->transaction_commit();
-assert('count($db->prepare_execute_fetch_all("SELECT * FROM foo WHERE a=?str?", "marijn")) === 1');
-
-$db->disconnect();
-
-?>

=== removed file 'database.old/sqltemplate.lib.php'
--- database.old/sqltemplate.lib.php	2009-07-20 20:39:48 +0000
+++ database.old/sqltemplate.lib.php	1970-01-01 00:00:00 +0000
@@ -1,504 +0,0 @@
-<?php
-
-/*
- * Anewt, Almost No Effort Web Toolkit, database module
- *
- * Copyright (C) 2004-2006  Wouter Bolsterlee <uws@xxxxxxxxx>
- * Copyright (C) 2004-2005  Jasper Looije <jasper@xxxxxxx>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA+
- */
-
-
-
-/* Query types */
-mkenum(
-		/* Data Manipulation Language (DML) */
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_SELECT',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_INSERT',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_UPDATE',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_DELETE',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_REPLACE',
-
-		/* Data Definition Language (DDL) */
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_CREATE',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_ALTER',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_DROP',
-
-		/* Transactions */
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_BEGIN',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_COMMIT',
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_ROLLBACK',
-
-		/* Unknown */
-		'ANEWT_DATABASE_SQL_QUERY_TYPE_UNKNOWN'
-		);
-
-
-/* Column types */
-mkenum(
-		/* Boolean */
-		'ANEWT_DATABASE_TYPE_BOOLEAN',
-
-		/* Numeric */
-		'ANEWT_DATABASE_TYPE_INTEGER',
-		'ANEWT_DATABASE_TYPE_FLOAT',
-
-		/* String */
-		'ANEWT_DATABASE_TYPE_STRING',
-
-		/* Dates and times */
-		'ANEWT_DATABASE_TYPE_DATE',
-		'ANEWT_DATABASE_TYPE_TIME',
-		'ANEWT_DATABASE_TYPE_DATETIME',
-		'ANEWT_DATABASE_TYPE_TIMESTAMP',
-
-		/* Raw */
-		'ANEWT_DATABASE_TYPE_RAW',
-
-		/* SQL internals */
-		'ANEWT_DATABASE_TYPE_COLUMN',
-		'ANEWT_DATABASE_TYPE_TABLE'
-);
-
-
-
-/**
- * SQL Template class with mandatory type checking. This class implements the
- * type checking logic for SQL queries.
- */
-class SQLTemplate {
-	var $db;             /**< \private Database object instance reference */
-	var $placeholders;   /**< \private List of parameters (placeholders) */
-	var $named_placeholders;   /**< \private List of named parameters (placeholders) */
-	var $named_mode = false; /**< \private are we using 'named mode' with named placeholders? */
-	var $sql_template;   /**< \private SQL template */
-
-	/**
-	 * Constructs a new SQLTemplate instance.
-	 *
-	 * \param $sql_template
-	 *   The template SQL string.
-	 *
-	 * \param $db
-	 *   Reference to the database object instance.
-	 *
-	 * \see SQLTemplate::parse
-	 */
-	function SQLTemplate($sql_template, &$db) {
-		assert('is_string($sql_template)');
-		assert('$db instanceof DB');
-
-		/* Initial values */
-		$this->db = &$db;
-		$this->placeholders = array();
-		$this->named_placeholders = array();
-		
-		/* Parse the template */
-		$this->parse($sql_template);
-	}
-
-
-	/**
-	 * Convert a column type string into the associated constant. This function
-	 * returns one of the <code>ANEWT_DATABASE_TYPE_*</code> constants, and
-	 * triggers and error if $type_str is not a valid identifier.
-	 *
-	 * Example: The string <code>int</code> results in the
-	 * <code>ANEWT_DATABASE_TYPE_INTEGER</code> constant.
-	 *
-	 * \param $type_str
-	 *   A string indicating a database type, e.g. <code>int</code>.
-	 *
-	 * \return
-	 *   Associated <code>ANEWT_DATABASE_TYPE_*</code> constant.
-	 */
-	public static function column_type_from_string($type_str)
-	{
-		assert('is_string($type_str);');
-		$mapping = array(
-			'bool'      => ANEWT_DATABASE_TYPE_BOOLEAN,
-			'boolean'   => ANEWT_DATABASE_TYPE_BOOLEAN,
-			'i'         => ANEWT_DATABASE_TYPE_INTEGER,
-			'int'       => ANEWT_DATABASE_TYPE_INTEGER,
-			'integer'   => ANEWT_DATABASE_TYPE_INTEGER,
-			'f'         => ANEWT_DATABASE_TYPE_FLOAT,
-			'float'     => ANEWT_DATABASE_TYPE_FLOAT,
-			'double'    => ANEWT_DATABASE_TYPE_FLOAT,
-			's'         => ANEWT_DATABASE_TYPE_STRING,
-			'str'       => ANEWT_DATABASE_TYPE_STRING,
-			'string'    => ANEWT_DATABASE_TYPE_STRING,
-			'varchar'   => ANEWT_DATABASE_TYPE_STRING,
-			'date'      => ANEWT_DATABASE_TYPE_DATE,
-			'datetime'  => ANEWT_DATABASE_TYPE_DATETIME,
-			'time'      => ANEWT_DATABASE_TYPE_TIME,
-			'timestamp' => ANEWT_DATABASE_TYPE_TIMESTAMP,
-			'r'         => ANEWT_DATABASE_TYPE_RAW,
-			'raw'       => ANEWT_DATABASE_TYPE_RAW,
-			'col'       => ANEWT_DATABASE_TYPE_COLUMN,
-			'column'    => ANEWT_DATABASE_TYPE_COLUMN,
-			'table'     => ANEWT_DATABASE_TYPE_TABLE,
-		);
-
-		if (array_key_exists($type_str, $mapping))
-			return $mapping[$type_str];
-
-		trigger_error(sprintf('Field type "%s" is unknown', $type_str), E_USER_ERROR);
-	}
-
-	/**
-	 * Parses a template string and extracts placeholders.
-	 *
-	 * \param $sql_template
-	 *   The template SQL string.
-	 */
-	function parse($sql_template) {
-		assert('is_string($sql_template)');
-
-		/* Since vsprintf is used to substitute escaped values into the sql
-		 * query later on, % characters need to be escaped. */
-		$sql_template = str_replace('%', '%%', $sql_template); // escape old values
-
-		/* Find placeholders fields. All placeholders start with ? followed by
-		 * a keyword and end with ? too. Examples ?string? and ?int? */
-		$fields = array();
-		$named_fieldspattern = '/\?([a-z]+):([^?]*)\?/i';
-		$fieldspattern = '/\?([a-z]+)\?/i';
-
-		if (preg_match_all($named_fieldspattern, $sql_template, $fields)) {
-			assert('!preg_match_all($fieldspattern, $sql_template, $dummy); // mixing named placeholders with anoymous placeholders is not supported');
-			$this->named_mode = true;	// switch to named placeholders
-
-			/* $fields[1] now contains the matches inside the first
-			 * parenthesized expression. Assign the special types to the params
-			 * list, so that proper validation and escaping/quoting can be done
-			 * when providing values to these placeholders. */
-			$match = 0;
-			foreach ($fields[0] as $field)
-			{
-				$this->named_placeholders[] = array(
-					'type' => SQLTemplate::column_type_from_string($fields[1][$match]),
-					'var' => $fields[2][$match]
-				);
-				$match++;
-			}
-
-			/* Replace all ?type:var? parts with %s to allow easy vsprintf
-			 * substitution when filling in values. Quoting the values is taken
-			 * care of in the fill() method. */
-			$sql_template = preg_replace($named_fieldspattern, '%s', $sql_template);
-
-		} elseif (preg_match_all($fieldspattern, $sql_template, $fields)) {
-			/* $fields[1] now contains the matches inside the first
-			 * parenthesized expression. Assign the special types to the params
-			 * list, so that proper validation and escaping/quoting can be done
-			 * when providing values to these placeholders. */
-			foreach ($fields[1] as $field)
-			{
-				$this->placeholders[] = SQLTemplate::column_type_from_string($field);
-			}
-
-			/* Replace all ?field? parts with %s to allow easy vsprintf
-			 * substitution when filling in values. Quoting the values is taken
-			 * care of in the fill() method. */
-			$sql_template = preg_replace($fieldspattern, '%s', $sql_template);
-		}
-		$this->sql_template = $sql_template;
-	}
-
-	/**
-	 * Fills in the valus in the SQL template. This method will check all values
-	 * for correctness to avoid nasty SQL injection vulnerabilities.
-	 *
-	 * \param $args
-	 *   Array with values to use for substitution.
-	 *
-	 * \return
-	 *   The query containing all values, quoted correctly.
-	 */
-	function fill($args=null) {
-		/* We accept either:
-		 * - no parameters
-		 * - multiple scalar parameters
-		 * - 1 array parameter with scalar elements
-		 * - 1 associative array parameter
-		 * - 1 container parameter
-		 */
-		$args = func_get_args();
-		if($this->named_mode) {
-			if (count($args) != 1) {
-				trigger_error('associative array or Container expected', E_USER_ERROR);
-			}
-			if($args[0] instanceof Container) {
-				$args = $args[0]->to_array();
-			} elseif(is_array($args[0])) {
-				$args = $args[0];
-			} else {
-				trigger_error('associative array or Container expected', E_USER_ERROR);
-			}
-
-			$numargs = count($this->named_placeholders);
-		} else {
-			if ((count($args) == 1) && is_numeric_array($args[0]))
-				$args = $args[0];
-	
-			assert('is_numeric_array($args)');
-	
-			if (count($args) != count($this->placeholders)) {
-				trigger_error(sprintf(
-					'Incorrect number of parameters to SQLTemplate::fill(): expected %d, got %d',
-					count($this->placeholders), count($args)), E_USER_ERROR);
-			};
-
-			$numargs = count($args);
-		}
-
-		/* Note: don't use foreach() here, because it copies the values in
-		 * memory and leaves the original values untouched! */
-		for ($i = 0; $i < $numargs; $i++) {
-			if($this->named_mode) {
-				$fieldtype = $this->named_placeholders[$i]['type'];
-				$var = $this->named_placeholders[$i]['var'];
-				if(!isset($args[$var])) {
-					$var = str_replace('-', '_', $var);	// Container replaces '-' with '_'
-					if(!array_key_exists($var, $args)) {
-						trigger_error(sprintf('SQLTemplate::fill(): missing expected parameter "%s"',
-							$this->named_placeholders[$i]['var']),
-							E_USER_ERROR);
-					}
-				}
-				$value = $args[$var];
-				$argname = "`".$var."'";
-			} else {
-				$fieldtype = $this->placeholders[$i];
-				$value = &$args[$i];
-				$argname = $i + 1;
-			}
-
-			/* Handle NULL values here. Escaping is not needed for NULL values. */
-			if (is_null($value)) {
-				$value = 'NULL';
-				if($this->named_mode) {
-					$arglist[$i] = $value;
-				}
-				continue;
-			}
-
-			/* The value is non-null. Perform very restrictive input sanitizing
-			 * based on the field type. */
-
-			switch ($fieldtype) {
-
-				case ANEWT_DATABASE_TYPE_BOOLEAN:
-
-					/* Integers: only accept 0 and 1 (no type juggling!) */
-					if (is_int($value)) {
-						if ($value === 0) {
-							$value = false;
-						} elseif ($value === 1) {
-							$value = true;
-						}
-					}
-
-					/* Strings: only accept literal "0" and "1" (no type juggling!) */
-					if (is_string($value)) {
-						if ($value === "0") {
-							$value = false;
-						} elseif ($value === "1") {
-							$value = true;
-						}
-					}
-
-					if (is_bool($value)) {
-						$value = $this->db->backend->escape_boolean($value);
-						break;
-					}
-
-					trigger_error(sprintf('Invalid boolean value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_INTEGER:
-
-					if (is_int($value)) {
-						$value = (string) $value;
-						break;
-					}
-					
-					if (is_string($value) && preg_match('/^-?\d+$/', $value))
-						break;
-
-					trigger_error(sprintf('Invalid integer value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_FLOAT:
-
-					// FIXME: this does not accept .123 (without a leading zero)
-					if (is_string($value) && preg_match('/^-?\d+(\.\d*)?$/', $value)) {
-						/* Enough checks done by the regex, no need to do any
-						 * formatting/escaping */
-						break;
-
-					/* Locale-agnostic float formatting */
-					} elseif (is_int($value) || is_float($value)) {
-						$value = number_format($value, 10, '.', '');
-						if (str_has_suffix($value, '.')) $value .= '0';
-						break;
-					}
-
-					trigger_error(sprintf('Invalid float value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_STRING:
-
-					/* Accept integers and objects with a render() method. */
-					if (is_int($value)) {
-						$value = (string) $value;
-					} elseif (is_object($value) && method_exists($value, 'render')) {
-						$value = $value->render();
-					}
-
-					/* From this point on, only strings are accepted. */
-					if (is_string($value)) {
-						$value = $this->db->backend->escape_string($value);
-						break;
-					}
-
-					trigger_error(sprintf('Invalid string value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_DATE:
-
-					if ($value instanceof AnewtDateTimeAtom)
-						$value = AnewtDateTime::sql_date($value);
-
-					if (is_string($value) && preg_match('/^\d{2,4}-\d{2}-\d{2}$/', $value)) {
-						$value = $this->db->backend->escape_date($value);
-						break;
-					}
-					if (is_string($value) && strtoupper($value) == "NOW") {
-						$value = "NOW()";
-						break;
-					}
-
-					if (is_string($value) && strtoupper($value) == 'NOW') {
-						$value = 'NOW()';
-						break;
-					}
-
-					trigger_error(sprintf('Invalid date value: "%s" on argument %s',
-								$value, $argname), E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_TIME:
-
-					if ($value instanceof AnewtDateTimeAtom)
-						$value = AnewtDateTime::sql_time($value);
-
-					if (is_string($value) && preg_match('/^\d{2}:\d{2}(:\d{2})?$/', $value)) {
-						$value = $this->db->backend->escape_time($value);
-						break;
-					}
-					if (is_string($value) && strtoupper($value) == "NOW") {
-						$value = "NOW()";
-						break;
-					}
-
-					if (is_string($value) && strtoupper($value) == 'NOW') {
-						$value = 'NOW()';
-						break;
-					}
-
-					trigger_error(sprintf('Invalid time value: "%s" on argument %s',
-								$value, $argname), E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_DATETIME:
-				case ANEWT_DATABASE_TYPE_TIMESTAMP:
-
-					if ($value instanceof AnewtDateTimeAtom)
-						$value = AnewtDateTime::sql($value);
-
-					if (is_string($value) && preg_match('/^\d{2,4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) {
-						$value = $this->db->backend->escape_datetime($value);
-						break;
-					}
-					if (is_string($value) && strtoupper($value) == "NOW") {
-						$value = "NOW()";
-						break;
-					}
-
-					if (is_string($value) && strtoupper($value) == 'NOW') {
-						$value = 'NOW()';
-						break;
-					}
-
-					trigger_error(sprintf('Invalid datetime or timestamp value: "%s" on argument %s',
-								$value, $argname), E_USER_ERROR);
-
-				case ANEWT_DATABASE_TYPE_RAW:
-					/* No checking, no escaping... use at your own risk ;-) */
-					break;
-
-
-				/* The column and table type are mostly for internal usage, it's
-				 * a BAD idea to use user data for these fields! */
-
-				case ANEWT_DATABASE_TYPE_COLUMN:
-
-					if (is_string($value) && preg_match('/^([a-z0-9_-]+\.)*[a-z0-9_-]+$/i', $value)) {
-						$value = $this->db->backend->escape_column_name($value);
-						break;
-					}
-
-					trigger_error(sprintf('Invalid column value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-
-				case ANEWT_DATABASE_TYPE_TABLE:
-
-					if (is_string($value) && preg_match('/^([a-z0-9_-]+\.)*[a-z0-9_-]+$/i', $value)) {
-						$value = $this->db->backend->escape_table_name($value);
-						break;
-					}
-
-					trigger_error(sprintf('Invalid table value: "%s" on argument %s', $value, $argname),
-							E_USER_ERROR);
-
-
-				default:
-					trigger_error('This is a bug! Fieldtype unknown',
-							E_USER_ERROR);
-					break;
-			}
-
-			assert('is_string($value)');
-
-			if($this->named_mode) {
-				$arglist[$i] = $value;
-			}
-		}
-
-		/* Now that all supplied values are validated and escaped properly, we
-		 * can easily substitute them into the query template. The %s
-		 * placeholders were already prepared during initial parsing. */
-		if($this->named_mode) {
-			$query = vsprintf($this->sql_template, $arglist);
-		} else {
-			$query = vsprintf($this->sql_template, $args);
-		}
-
-		return $query;
-	}
-}
-
-?>