<? /** * 文件数据库函数 * 约定: * 数据库名为同名目录 * 数据表名后缀为 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 "," |