<?
/**
* 文件数据库函数
* 约定:
* 数据库名为同名目录
* 数据表名后缀为 tab
* 索引文件后缀为 ind
* 管理文件名为 数据库同名目录/manage.ini
* 备注型字段以独立文件存在,表中保留文件名
* 字段以定长方式或csv方式保存,由管理文件指定
* 每行一条记录
* 索引文件以二进制方式包存键值(定长)和偏移量(长整型)
*
** 函数列表(前面有:+ 为已实现,- 为部分实现,其余为尚未实现)
套用 MySQL 函数集 取名 FILE_DB
* file_affected_rows: 得到 FILE_DB 最后操作影响的列数目。
*-file_close: 关闭 FILE_DB 服务器连接。
* file_connect: 打开 FILE_DB 服务器连接。
*+file_create_db: 建立一个 FILE_DB 新数据库。
* file_data_seek: 移动内部返回指针。
* file_db_query: 送查询字符串 (query) 到 FILE_DB 数据库。
* file_drop_db: 移除数据库。
* file_errno: 返回错误信息代码。
* file_error: 返回错误信息。
*+file_fetch_array: 返回数组资料。
* file_fetch_field: 取得字段信息。
* file_fetch_lengths: 返回单列各栏资料最大长度。
* file_fetch_object: 返回类资料。
*+file_fetch_row: 返回单列的各字段。
*+file_field_name: 返回指定字段的名称。
* file_field_seek: 配置指针到返回值的某字段。
* file_field_table: 获得目前字段的资料表 (table) 名称。
* file_field_type: 获得目前字段的类型。
* file_field_flags: 获得目前字段的标志。
* file_field_len: 获得目前字段的长度。
* file_free_result: 释放返回占用内存。
* file_insert_id: 返回最后一次使用 INSERT 指令的 ID。
* file_list_fields: 列出指定资料表的字段 (field)。
* file_list_dbs: 列出 FILE_DB 服务器可用的数据库 (database)。
* file_list_tables: 列出指定数据库的资料表 (table)。
*+file_num_fields: 取得返回字段的数目。
*+file_num_rows: 取得返回列的数目。
* file_pconnect: 打开 FILE_DB 服务器持续连接。
*-file_query: 送出一个 query 字符串。
* file_result: 取得查询 (query) 的结果。
* file_select_db: 选择一个数据库。
* file_tablename: 取得资料表名称。
*/
/**
*
*
$cmp_key;
/** 连结至 FILE_DB 资料库
* @param 数据库名
*/
function &file_connect($dbname) {
$filename = $dbname."/manage.ini";
if(!file_exists($filename))
die("数据库:$dbnamee不存在");
$fp = fopen($filename,"r");
$s = fgets($fp,filesize($filename)+1);
fclose($fp);
$db = unserialize($s);
return $db;
}
/** 关闭 FILE_DB 连结
*
*/
function file_close(&$connection_id) {
unset($connection_id);
}
/** 建立 FILE_DB 数据库
* @param 数据库名
*/
function file_create_db($dbname) {
if(! @mkdir($dbname,0700))
$err = "目录已存在";
$filename = $dbname."/manage.ini";
$ar[path] = "$dbname/";
$s = serialize($ar);
$fp = fopen($filename,"w");
fputs($fp,$s);
fclose($fp);
}
/** 执行 SQL 指令
*
*/
function file_query($query,&$connection_id,$_line = __LINE__) {
// 解析 $query
$query = eregi_replace("[ ]+"," ",$query);
$ar = split(" ",trim(str_replace(""," ",$query)));
$query = eregi_replace("\r?\n","",$query);
$ch = each($ar);
switch(strtoupper($ch[1])) {
case "CREATE":
if(! eregi("create table (.+) [(] *(.+)[)] *$",$query,$pp))
die("SQL表达式错,$_line");
$table = $pp[1];
if(empty($connection_id[$table])) {
// 解析字段表达式
$ar = split(",",$pp[2]);
while(list($key,$value) = each($ar)) {
$str = split(" ",trim($value));
eregi("([a-z0-9]+) ([a-z]+) ?([(]([0-9]+)[)])?(.+)?",$value,$pp);
$field[name] = $pp[1];
$field[type] = $pp[2];
$field[len] = $pp[4];
$field[style] = trim($pp[5]);
$sss[] = $field;
}
$connection_id[$table] = array(
"fields" => $sss,
"filename" => $table.".tab",
"type" => "CSV"
);
}
$fp = fopen($connection_id[path]."manage.ini","w");
fputs($fp,serialize($connection_id));
fclose($fp);
break;
case "SELECT":
if(! eregi("select (.+) from ([^ ]+) *(.+)*$",$query,$pp))
die("SQL表达式错,$_line");
// 解析SQL语句的控制部分
$exte = $pp[3];
if(! eregi("where ",$exte))
$exte = "where true ".$exte;
if(! eregi("order ",$exte))
$exte .= "order by 0";
if(! eregi("group ",$exte))
$exte = eregi_replace("order ","group by _ order ",$exte);
eregi("where (.+) *group by (.+) order by (.+)",$exte,$regs);
$filter = trim($regs[1]);
$group = trim($regs[2]);
$order = trim($regs[3]);
if($group == "_") $group = "";
if($order == "0") $order = "";
// 读取数据文件
if(empty($connection_id[$pp[2]]))
die("表".$pp[2]."不存在");
$table = $connection_id[$pp[2]];
if(!file_exists($connection_id[path].$table[filename])) {
// 数据表尚未建立
return false;
}else {
// 获取表定义字段名
for($i=0;$i<count($table[fields]);$i++)
$defaultfield[] = $table[fields][$i][name];
$defaultfield = array_flip($defaultfield);
// 解析筛选表达式
if($filter != "true") {
$filter = eregi_replace(" and "," && ",$filter);
$filter = eregi_replace(" or "," (北联网教程,专业提供视频软件下载)
……