<?php

/*

mod_mysql_scheme introduces the "mysql://" protocol stream, which allows
you to use database contents with file functions like fopen().

mysql://user:pw@mysql-server/DB_name/TABLE/contentCOLUMN?matchCOLUMN=str

For Nanoweb you should use this together with the .lnk files as provided
by mod_lnk. You could create a file called "mysql.lnk" with just the line
"mysql://mysqld/myfiles/files/txt/?filename=" in it, so you could
reference the contents of the database column "text" from outside via
"http://localhost/mysql.lnk/indexname".

*/


class mod_mysql_scheme {

	var $modname="PHP mysql:// scheme support";
	var $modtype="core_php";

	function init() {
		if (function_exists("stream_register_wrapper")) {
			stream_register_wrapper("mysql", "mysqlStream");
		}
		else {
			techo("mysql:// stream requires PHP >= 4.3", NW_EL_ERROR);
		}
	}
}


class mysqlStream {

	var $db_handle;
	var $pos=0;
	var $eof=1;


	function stream_open($path, $mode, $options, &$opened_path) {

		if ($mode[0] != "r") {
			trigger_error("mysql:// stream can be used for reading only");
			return;
		}

		$desc = parse_url($path);
		list($uu, $desc["database"], $desc["table"], $desc["column"], $uu) = explode("/", $desc["path"], 5);
		parse_str($desc["query"], $querray);

		$where = "";
		foreach ($querray as $t=>$i) {
			if ($where) { $where .= " AND "; }
			$i = addslashes(urldecode(ltrim($i, "/")));
			$where .= '((' . $t . '="' . $i .
			'") OR (' . $t . '="/' . $i . '"))';
		}
		if ($where) { $where = "WHERE " . $where; }
		$desc["where"] = $where;

		$this->desc = $desc;

		if (($this->db_handle = mysql_pconnect($desc["host"], $desc["user"], $desc["pass"])) 
		   && mysql_query("USE " . $desc["database"], $this->db_handle))
		{
			extract($desc);

			if ($r = mysql_query("SELECT CONCAT($column) FROM $table $where", $this->db_handle)) {

				list($this->content) = mysql_fetch_row($r);
				mysql_free_result($r);

				$this->pos = 0;
				$this->eof = 0;
	 			return(true);
			}
		}

		echo mysql_error();print_r($this);print_r($desc);
		return(false);
	}


	function stream_read($count) {

		$this->pos += $count;
		if ($this->pos > strlen($this->content)) {
			$this->eof = 1;
		}
		return(substr($this->content, $this->pos - $count, $count));
	}


	function stream_close() {
		mysql_close($this->db_handle);
	}


	function stream_eof() {
		return($this->eof);
	}


	function stream_write($data) {
		trigger_error("cannot write to mysql://");
	}


	function stream_tell() {
		return($this->pos);
	}


	function stream_seek($offs,$whence) {
		switch ($whence) {
			case SEEK_SET: $this->pos = $offs; break;
			case SEEK_CURR: $this->pos += $offs; break;
			default: $this->pos = strlen($this->content) - $offs;
		}
	}

}


?>