public static function install($expiration=7200) {

		$dtnow = $expire = null;
		extract(self::fragments($expiration));
		$sql = self::$sql;

		# user table

		$user_table = ("
			CREATE TABLE udata (
				uid %s,
				uname VARCHAR(64) UNIQUE,
				upass VARCHAR(64),
				usalt VARCHAR(16),
				since TIMESTAMP NOT NULL DEFAULT %s,
				email VARCHAR(64),
				email_verified INT NOT NULL DEFAULT 0,
				fname VARCHAR(128),
				site VARCHAR(128)
			) %s;
		");
		$user_table = sprintf($user_table, $index, $dtnow, $engine);
		$sql->query_raw($user_table);

		# default user

		$root_salt = self::$admin_store->generate_secret(
			'root', null, 16);
		$root_pass = self::$admin_store->hash_password(
			'root', 'admin', $root_salt);
		$sql->insert('udata', [
			'uid' => 1,
			'uname' => 'root',
			'upass' => $root_pass,
			'usalt' => $root_salt,
		]);

		# session table

		$session_table = ("
			CREATE TABLE usess (
				sid %s,
				uid INTEGER REFERENCES udata(uid) ON DELETE CASCADE,
				token VARCHAR(64),
				expire TIMESTAMP NOT NULL DEFAULT %s
			) %s;
		");
		$session_table = sprintf(
			$session_table, $index, $expire, $engine);
		$sql->query_raw($session_table);

		# session view

		$user_session_view = ("
			CREATE VIEW v_usess AS
				SELECT
					udata.*,
					usess.sid,
					usess.token,
					usess.expire
				FROM udata, usess
				WHERE
					udata.uid=usess.uid;
		");
		$sql->query_raw($user_session_view);

		# metadata

		$sql->query_raw(sprintf("
			CREATE TABLE meta (
				version VARCHAR(24) NOT NULL DEFAULT '0.0'
			);
		", $engine));
		$sql->insert('meta', [
			'version' => self::TABLE_VERSION,
		]);
	}