class TxtDb{
var $dataBase;
var $dataRows;
var $dataCache;
var $dataError;
function TxtDb($dataBase = "data"){
$this->dataBase = $dataBase;
$this->dataCache = "cache";
$this->dataError = null;
}
function insert($tableName,$args){
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r+")){
$this->dataError = "数据表打开失败";
return false;
}else if(!strstr(fread($fp,20),"TDB")){
$this->dataError = "数据库文件被破坏或者格式错误";
fclose($fp);
return false;
}else{
fseek($fp,20,SEEK_CUR);
for($i=0,$result="1",$length=0,$tmp=explode(';',trim(fread($fp,160)));$i
list($key,$value) = explode(':',$tmp[$i]);
$length += $value;
if(!array_key_exists($key,$args)){
$result .= str_pad("",$value);
}else if(strlen($args[$key])>$value){
$this->dataError = "用户字段太长 '$key' 错误";
fclose($fp);
return false;
}else{
$result .= str_pad($args[$key],$value);
}
}
fseek($fp,0,SEEK_END);
fwrite($fp,$result);
fclose($fp);
return true;
}
}
function update($tableName,$rows,$args){
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r+")){
$this->dataError = "数据表打开失败";
return false;
}else if(!strstr(fread($fp,20),"TDB")){
$this->dataError = "数据库文件被破坏或者格式错误";
fclose($fp);
return false;
}else{
fseek($fp,20,SEEK_CUR);
for($i=0,$result="1",$length=0,$tmp=explode(';',trim(fread($fp,160)));$i
list($key,$value) = explode(':',$tmp[$i]);
$length += $value;
if(!array_key_exists($key,$args)){
$result .= str_pad("",$value);
}else if(strlen($args[$key])>$value){
$this->dataError = "用户字段太长 '$key' 错误";
fclose($fp);
return false;
}else{
$result .= str_pad($args[$key],$value);
}
}
if(fseek($fp,$rows*strlen($result)+200,SEEK_SET) == 0){
fwrite($fp,$result);
fclose($fp);
return true;
}else{
fclose($fp);
$this->dataError = "记录更新失败,数据定位失败";
return false;
}
}
}
function select($table,$rows){
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
$this->dataError = "数据表打开失败";
return false;
}else if(!strstr(fread($fp,20),"TDB")){
$this->dataError = "数据库文件被破坏或者格式错误";
fclose($fp);
return false;
}else{
fseek($fp,20,SEEK_CUR);
for($i=0,$result="1",$length=0,$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i
list($key,$value) = explode(':',$tmp[$i]);
$head[$key] = $value;
$length += $value;
}
if(fseek($fp,$rows*($length+1)+200,SEEK_SET) == 0){
$result = array('rows'=>$rows);
foreach($head AS $key=>$value)$result[$key] = fread($fp,$value);
fclose($fp);
return $result;
}else{
fclose($fp);
$this->dataError = "记录更新失败,数据定位失败";
return false;
}
}
}
function getAll($tableName,$query,$order = "0,desc",$limit = "0,100000"){
$cacheFile = $this->dataBase."/".$this->dataCache."/".md5("$tableName:$query:$order").".tdc";
list($order,$ordertype,$limit,$end) = explode(",",$order.','.$limit);
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
$this->dataError = "数据表打开失败";
return false;
}else if(!strstr(fread($fp,20),"TDB")){
$this->dataError = "数据库文件被破坏或者格式错误";
fclose($fp);
return false;
}else{
fseek($fp,20,SEEK_CUR);
for($i=0,$length=0,$result="1",$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i
list($key,$value) = explode(':',$tmp[$i]);
$head[$key] = $value;
$length += $value;
}
if(@filemtime($cacheFile) > time()-1000){
if($fp1 = fopen($cacheFile,"r")){
$result = unpack("Vrows",fread($fp1,4));
$this->dataRows = $result['rows'];
if(fseek($fp1,($limit+1)*4,SEEK_SET) == 0){
$result = unpack("V*",fread($fp1,$end*4));
fclose($fp1);
}else{
fclose($fp);
fclose($fp1);
return false;
}
}else{
$this->dataError = "缓存文件打开错误";
fclose($fp);
fclose($fp1);
return false;
}
}else if(fseek($fp,200,SEEK_SET) == 0){
$i = 0;
foreach($head AS $key=>$value){
$query = str_replace("@$key","@".$i++,$query);
}
$result = array();
preg_match_all('/@(\d+)/si',$query,$tmp);
$tmp[1][]= $order;
$query = preg_replace('/@(\d+)/si','$row[\1]',$query);
$execute = '$i=0;while(true){if(strlen($type=fread($fp,1))!=1)break;$row=array(\'rows\'=>$i++);';
for($i=0,$id=empty($tmp[1])?100:max($tmp[1]),$sum=0,$values=array_values($head);$i
$sum += $values[$i];
$execute .= '$row[]=trim(fread($fp,'.$values[$i].'));';
if($id <= $i){
$execute .= 'fseek($fp,'.($length-$sum).',SEEK_CUR);';
break;
}
}
eval($execute.'if($type==\'1\' && '.$query.'){$result[] = array($i-1,$row[$order]);}}');
usort($result,
create_function('$a,$b',$ordertype=="desc"?'return strcmp($a[1],$b[1]);':'return strcmp($b[1],$a[1]);'));
for($i=0,$tmp='';$i
if($fp1 = fopen($cacheFile,"w")){
fwrite($fp1,pack("V",($this->dataRows = strlen($tmp)/4)).$tmp);
fclose($fp1);
}
$result = unpack("V*",substr($tmp,$limit*4,$end*4));
}else{
fclose($fp);
$this->dataError = "记录查询失败,数据定位失败";
return false;
}
$tmp = $row = array();
foreach($result as $rows){
fseek($fp,$rows*($length+1)+201,SEEK_SET);
foreach($head AS $key=>$value){
$row[$key] = trim(fread($fp,$value));
}
$tmp[] = $row;
}
fclose($fp);
return $tmp;
}
}
function remove($tableName,$query){
if(!$fp = fopen($this->dataBase."/".$tableName.".tdb","r")){
$this->dataError = "数据表打开失败";
return false;
}else if(!strstr(fread($fp,20),"TDB")){
$this->dataError = "数据库文件被破坏或者格式错误";
fclose($fp);
return false;
}else{
fseek($fp,20,SEEK_CUR);
for($i=0,$length=0,$result="1",$head=array(),$tmp=explode(';',trim(fread($fp,160)));$i
list($key,$value) = explode(':',$tmp[$i]);
$head[$key] = $value;
$length += $value;
}
$i = 0;
foreach($head AS $key=>$value){
$query = str_replace("@$key","@".$i++,$query);
}
$result = array();
preg_match_all('/@(\d+)/si',$query,$tmp);
$tmp[1][]= $order;
$query = preg_replace('/@(\d+)/si','$row[\1]',$query);
$execute = '$i=0;while(true){if(strlen($type=fread($fp,1))!=1)break;$row=array(\'rows\'=>$i++);';
for($i=$rows=0,$id=empty($tmp[1])?100:max($tmp[1]),$sum=0,$values=array_values($head);$i
$sum += $values[$i];