[转]某文本数据库blog作者写的文本数据库操作类,很不错

转载 2006年06月16日 17:37:00

 

作者的1.0版:

<?
/*
本代码开源,您可以对其进行修改.
下面文字请不要修改.
*********************************************
php文本数据库类1.0版
powerd by bpns
mysite:http://space.tju.cn/site/redboy/
2006-4-20
*********************************************

为了您的数据库安全,请在此程序中更改您的数据默认目录

将function TxtDB($name,$mod='w',$path='my_dbm')
中$path='my_dbm'修改成你自己设定的目录,如$path='abc123_dbm',
并将根目录下的my_dbm文件夹对行对应的更名.
*/

class 
TxtDB
{
  var 
$name='';
//文本数据库名
  
var $path=''
;
  var 
$minLen=20
;
  var 
$isError
;
  var 
$dbh
;
  var 
$indxh
;
  var 
$lfth
;
  var 
$lckh
;
  var 
$rcdCnt=0
;
  var 
$maxID=0
;
  var 
$leftCnt=0
;
  var 
$DBend=0
;
  var 
$mod='w'
;
  function 
TxtDB($name,$mod='w',$path='bpns_dbm')
//修改数据库的默认文件夹在此修改
  
{
    
$this->name=$name
;
    
$this->path=$path.'/'.$name
;
    
$this->isError=0
;
    
$this->mod=$mod
;
    
$path=$this->path
;
    if (
$name!=''
)
    {
    @
mkdir($this->path,0777
);
    if (!
file_exists($path.'/'.$name.'.tdb')) $this->dbh=fopen($this->path.'/'.$name.'.tdb','w+'
);
    else 
$this->dbh=fopen($path.'/'.$name.'.tdb','r+'
);
    if (!
file_exists($path.'/'.$name.'.indx')) $this->indxh=fopen($this->path.'/'.$name.'.indx','w+'
);
    else 
$this->indxh=fopen($path.'/'.$name.'.indx','r+'
);
    if (!
file_exists($path.'/'.$name.'.lft')) $this->lfth=fopen($this->path.'/'.$name.'.lft','w+'
);
    else 
$this->lfth=fopen($this->path.'/'.$name.'.lft','r+'
);
    if (
$this->mod=='w'
)
    {
     
$this->lckh=fopen($this->path.'/'.$name.'.lck','w'
);
     
flock($this->lckh,2
);
     
fwrite($this->lckh,'lck');
//lock the datebase
    
}
    
$rcd=$this->getRcd(0
);
    
$this->rcdCnt=$rcd[id
];
    
$this->maxID=$rcd[loc
];
    
$this->DBend=$rcd[len
];
    
$rcd=$this->getLeft(0
);
    
$this->leftCnt=$rcd[loc
];
    }
    else 
$this->isError=1
;
  }
  function 
setRcd($rid,$id,$loc,$len
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=pack('III',$id,$loc,$len
);
    
fwrite($this->indxh,$str,12
);
  }
  function 
getRcd($rid
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=fread($this->indxh,12
);
    
$rcd
=array();
    
$rcd[id]=str2int($str
);
    
$rcd[loc]=str2int(substr($str,4,4
));
    
$rcd[len]=str2int(substr($str,8,4
));
    return 
$rcd
;
  }
  function 
setLeft($lid,$loc,$len
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=pack('II',$loc,$len
);
    
fwrite($this->lfth,$str,8
);
  }
  function 
getLeft($lid
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=fread($this->lfth,8
);
    
$rcd[loc]=str2int($str
);
    
$rcd[len]=str2int(substr($str,4,4
));
    return 
$rcd
;
  }
  
  function 
clear
()
  {
    
$this->setRcd(0,0,0,0
);
    
$this->setLeft(0,0,0
);
  }
  function 
close
()
  {
    @
fclose($this->dbh
);
    @
fclose($this->indxh
);
    @
fclose($this->lfth
);
    @
fclose($this->lckh
);
  }
  
  function 
seekSpace($len
)
  {
    
$res=array('loc'=>0,'len'=>0
);
    if (
$this->leftCnt<1) return $res
;
    
$find=0
;
    
$min=1000000
;
    for (
$i=$this->leftCnt;$i>0;$i
--)
    {
      
$res=$this->getLeft($i
);
      if (
$res[len]==$len) {$find=$i
;break;}
      else if(
$res[len]>$len
)
      {
         if (
$res[len]-$len<$min
)
         {
           
$min=$res[len]-$len
;
           
$find=$i
;
         }
      }
    }
    if (
$find
)
    {
      
$res=$this->getLeft($find
);
      if (
$res[len]<2*$len
)
      {
       
fseek($this->lfth,($find+1)*8
);
       
$str=fread($this->lfth,($this->leftCnt-$find)*8
);
       
fseek($this->lfth,$find*8
);
       
fwrite($this->lfth,$str
);
       
$this->leftCnt
--;
       
$this->setLeft(0,$this->leftCnt,0
);
       return 
$res
;
      }
      else
      {
        
$rs
=array();
        
$rs[loc]=$res[loc
];
        
$rs[len]=$len
;
        
$res[loc]+=$len
;
        
$this->setLeft($find,$res[loc],$res[len]-$len
);
        return 
$rs
;
      }
    }
    else
//fail
    
{
      
$res[len]=0
;
      return 
$res
;
    }
  }
  function 
insert($content,$len=0)
//return with record id
  
{
    
$res=array('loc'=>0
);
    if (
$this->mod!='w') return 0
;
    if (!
$len$len=strlen($content
); 
    if (
$len<$this->minLen$len=$this->minLen
;
    if (
$this->leftCnt$res=$this->seekSpace($len
);
    if (!
$res[len
])
    {
      
$res[loc]=$this->DBend
;
      
$res[len]=$len
;
    }
    if (
$res[loc]+$res[len]>$this->DBend$this->DBend=$res[loc]+$res[len
];
    
//echo $this->DBend.'<br>';
    
$this->maxID
++;
    
$this->rcdCnt
++;
    
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    
$this->setRcd($this->rcdCnt,$this->maxID,$res[loc],$res[len
]);
    
fseek($this->dbh,$res[loc
]);
    
fwrite($this->dbh,$content,$len
);
    return 
$this->maxID
;
  }
  function 
findByID($id
)
  {
    if (
$id<or $id>$this->maxID or $this->rcdCnt<1) return 0
;
    
$left=1
;
    
$right=$this->rcdCnt
;
    while(
$left<$right
)
    {
      
$mid=(int)(($left+$right)/2
);
      if (
$mid==$left or $mid==$right
) break;
      
$rcd=$this->getRcd($mid
);
      if (
$rcd[id]==$id) return $mid
;
      else if(
$id<$rcd[id]) $right=$mid
;
      else 
$left=$mid
;
    }
    
//$rcd=$this->getRcd($mid);
    //if ($rcd[id]==$id) return $mid;
    
$rcd=$this->getRcd($left
);
    if (
$rcd[id]==$id) return $left
;
    
$rcd=$this->getRcd($right
);
    if (
$rcd[id]==$id) return $right
;
    return 
0
;
  }
  function 
delete($id
)
  {
    if (
$this->mod!='w') return 0
;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    
$res=$this->getRcd($rid
);
    
fseek($this->indxh,($rid+1)*12
);
    
$str=fread($this->indxh,($this->rcdCnt-$i)*12
);
    
fseek($this->indxh,$rid*12
);
    
fwrite($this->indxh,$str
);
    
$this->rcdCnt
--;
    if (
$res[loc]+$res[len]==$this->DBend
)
    {
      
$this->DBend=$res[loc
];
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    }
    else
    {
     
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
     
$this->leftCnt
++;
     
$this->setLeft(0,$this->leftCnt,0
);
     
$this->setLeft($this->leftCnt,$res[loc],$res[len
]);
    }
  }
  function 
update($id,$newcontent,$len=0
)
  {
    if (
$this->mod!='w'
) return;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    if (!
$len$len=strlen($newcontent
); 
    
$rcd=$this->getRcd($rid
);
    if (
$rcd[len]<$len
)
    {
      
$this->leftCnt
++;
      
$this->setLeft(0,$this->leftCnt,0
);
      
$this->setLeft($this->leftCnt,$rcd[loc],$rcd[len
]);
      
$rcd[loc]=$this->DBend
;
      
$rcd[len]=$len
;
      
$this->DBend+=$len
;
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
      
$this->setRcd($rid,$rcd[id],$rcd[loc],$rcd[len
]);
    }
    
fseek($this->dbh,$rcd[loc
]);
    
fwrite($this->dbh,$newcontent,$len
);
    
//echo $id.'<br>'.$content.'<br>'.$len;
  
}
  function 
selectByRid($rid
)
  {
    
$res=array('id'=>0,'content'=>''
);
    if (
$rid<or $rid>$this->rcdCnt) return $res
;
    else 
$rcd=$this->getRcd($rid
);
    
$res[id]=$rcd[id
];
    
$res[len]=$rcd[len
];
    
fseek($this->dbh,$rcd[loc
]);
    
$res[content]=fread($this->dbh,$rcd[len
]);
    return 
$res
;
  }
  function 
select($id
)
  {
    return 
$this->selectByRid($this->findByID($id
));
  }
  function 
backup
()
  {
    
copy($this->path.'/'.$this->name.'.tdb',$this->path.'/'.$this->name.'.tdb.bck'
);
    
copy($this->path.'/'.$this->name.'.indx',$this->path.'/'.$this->name.'.indx.bck'
);
    
copy($this->path.'/'.$this->name.'.lft',$this->path.'/'.$this->name.'.lft.bck'
);
  }
  function 
recover
()
  {
    
copy($this->path.'/'.$this->name.'.tdb.bck',$this->path.'/'.$this->name.'.tdb'
);
    
copy($this->path.'/'.$this->name.'.indx.bck',$this->path.'/'.$this->name.'.indx'
);
    
copy($this->path.'/'.$this->name.'.lft.bck',$this->path.'/'.$this->name.'.lft'
);
  }
}
?>

作者的2.0版,生成dbm:

<?
class 
TxtDB
{
  var 
$name='';
//文本数据库名
  
var $path=''
;
  var 
$minLen=20
;
  var 
$isError
;
  var 
$dbh
;
  var 
$indxh
;
  var 
$lfth
;
  var 
$lckh
;
  var 
$rcdCnt=0
;
  var 
$maxID=0
;
  var 
$leftCnt=0
;
  var 
$DBend=0
;
  var 
$mod='w'
;
  function 
TxtDB($name,$mod='w',$path='bpns_dbm'
)
  {
    
$this->name=$name
;
    
$this->path=$path.'/'.$name
;
    
$this->isError=0
;
    
$this->mod=$mod
;
    
$path=$this->path
;
    if (
$name!=''
)
    {
    @
mkdir($this->path,0777
);
    if (!
file_exists($path.'/'.$name.'.tdb')) $this->dbh=fopen($this->path.'/'.$name.'.tdb','w+'
);
    else 
$this->dbh=fopen($path.'/'.$name.'.tdb','r+'
);
    if (!
file_exists($path.'/'.$name.'.indx')) $this->indxh=fopen($this->path.'/'.$name.'.indx','w+'
);
    else 
$this->indxh=fopen($path.'/'.$name.'.indx','r+'
);
    if (!
file_exists($path.'/'.$name.'.lft')) $this->lfth=fopen($this->path.'/'.$name.'.lft','w+'
);
    else 
$this->lfth=fopen($this->path.'/'.$name.'.lft','r+'
);
    if (
$this->mod=='w'
)
    {
     
$this->lckh=fopen($this->path.'/'.$name.'.lck','w'
);
     
flock($this->lckh,2
);
     
fwrite($this->lckh,'lck');
//lock the datebase
    
}
    
$rcd=$this->getRcd(0
);
    
$this->rcdCnt=$rcd[id
];
    
$this->maxID=$rcd[loc
];
    
$this->DBend=$rcd[len
];
    
$rcd=$this->getLeft(0
);
    
$this->leftCnt=$rcd[loc
];
    }
    else 
$this->isError=1
;
  }
  function 
setRcd($rid,$id,$loc,$len
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=pack('III',$id,$loc,$len
);
    
fwrite($this->indxh,$str,12
);
  }
  function 
getRcd($rid
)
  {
    
fseek($this->indxh,$rid*12
);
    
$str=fread($this->indxh,12
);
    
$rcd
=array();
    
$rcd[id]=str2int($str
);
    
$rcd[loc]=str2int(substr($str,4,4
));
    
$rcd[len]=str2int(substr($str,8,4
));
    return 
$rcd
;
  }
  function 
setLeft($lid,$loc,$len
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=pack('II',$loc,$len
);
    
fwrite($this->lfth,$str,8
);
  }
  function 
getLeft($lid
)
  {
    
fseek($this->lfth,$lid*8
);
    
$str=fread($this->lfth,8
);
    
$rcd[loc]=str2int($str
);
    
$rcd[len]=str2int(substr($str,4,4
));
    return 
$rcd
;
  }
  
  function 
clear
()
  {
    
$this->setRcd(0,0,0,0
);
    
$this->setLeft(0,0,0
);
  }
  function 
close
()
  {
    @
fclose($this->dbh
);
    @
fclose($this->indxh
);
    @
fclose($this->lfth
);
    @
fclose($this->lckh
);
  }
  
  function 
seekSpace($len
)
  {
    
$res=array('loc'=>0,'len'=>0
);
    if (
$this->leftCnt<1) return $res
;
    
$find=0
;
    
$min=1000000
;
    for (
$i=$this->leftCnt;$i>0;$i
--)
    {
      
$res=$this->getLeft($i
);
      if (
$res[len]==$len) {$find=$i
;break;}
      else if(
$res[len]>$len
)
      {
         if (
$res[len]-$len<$min
)
         {
           
$min=$res[len]-$len
;
           
$find=$i
;
         }
      }
    }
    if (
$find
)
    {
      
$res=$this->getLeft($find
);
      if (
$res[len]<2*$len
)
      {
       
fseek($this->lfth,($find+1)*8
);
       
$str=fread($this->lfth,($this->leftCnt-$find)*8
);
       
fseek($this->lfth,$find*8
);
       
fwrite($this->lfth,$str
);
       
$this->leftCnt
--;
       
$this->setLeft(0,$this->leftCnt,0
);
       return 
$res
;
      }
      else
      {
        
$rs
=array();
        
$rs[loc]=$res[loc
];
        
$rs[len]=$len
;
        
$res[loc]+=$len
;
        
$this->setLeft($find,$res[loc],$res[len]-$len
);
        return 
$rs
;
      }
    }
    else
//fail
    
{
      
$res[len]=0
;
      return 
$res
;
    }
  }
  function 
insert($content,$len=0)
//return with record id
  
{
    
$res=array('loc'=>0
);
    if (
$this->mod!='w') return 0
;
    if (!
$len$len=strlen($content
); 
    if (
$len<$this->minLen$len=$this->minLen
;
    if (
$this->leftCnt$res=$this->seekSpace($len
);
    if (!
$res[len
])
    {
      
$res[loc]=$this->DBend
;
      
$res[len]=$len
;
    }
    if (
$res[loc]+$res[len]>$this->DBend$this->DBend=$res[loc]+$res[len
];
    
//echo $this->DBend.'<br>';
    
$this->maxID
++;
    
$this->rcdCnt
++;
    
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    
$this->setRcd($this->rcdCnt,$this->maxID,$res[loc],$res[len
]);
    
fseek($this->dbh,$res[loc
]);
    
fwrite($this->dbh,$content,$len
);
    return 
$this->maxID
;
  }
  function 
findByID($id
)
  {
    if (
$id<or $id>$this->maxID or $this->rcdCnt<1) return 0
;
    
$left=1
;
    
$right=$this->rcdCnt
;
    while(
$left<$right
)
    {
      
$mid=(int)(($left+$right)/2
);
      if (
$mid==$left or $mid==$right
) break;
      
$rcd=$this->getRcd($mid
);
      if (
$rcd[id]==$id) return $mid
;
      else if(
$id<$rcd[id]) $right=$mid
;
      else 
$left=$mid
;
    }
    
//$rcd=$this->getRcd($mid);
    //if ($rcd[id]==$id) return $mid;
    
$rcd=$this->getRcd($left
);
    if (
$rcd[id]==$id) return $left
;
    
$rcd=$this->getRcd($right
);
    if (
$rcd[id]==$id) return $right
;
    return 
0
;
  }
  function 
delete($id
)
  {
    if (
$this->mod!='w') return 0
;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    
$res=$this->getRcd($rid
);
    
fseek($this->indxh,($rid+1)*12
);
    
$str=fread($this->indxh,($this->rcdCnt-$i)*12
);
    
fseek($this->indxh,$rid*12
);
    
fwrite($this->indxh,$str
);
    
$this->rcdCnt
--;
    if (
$res[loc]+$res[len]==$this->DBend
)
    {
      
$this->DBend=$res[loc
];
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
    }
    else
    {
     
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
     
$this->leftCnt
++;
     
$this->setLeft(0,$this->leftCnt,0
);
     
$this->setLeft($this->leftCnt,$res[loc],$res[len
]);
    }
  }
  function 
update($id,$newcontent,$len=0
)
  {
    if (
$this->mod!='w'
) return;
    
$rid=$this->findByID($id
);
    if (!
$rid
) return;
    if (!
$len$len=strlen($newcontent
); 
    
$rcd=$this->getRcd($rid
);
    if (
$rcd[len]<$len
)
    {
      
$this->leftCnt
++;
      
$this->setLeft(0,$this->leftCnt,0
);
      
$this->setLeft($this->leftCnt,$rcd[loc],$rcd[len
]);
      
$rcd[loc]=$this->DBend
;
      
$rcd[len]=$len
;
      
$this->DBend+=$len
;
      
$this->setRcd(0,$this->rcdCnt,$this->maxID,$this->DBend
);
      
$this->setRcd($rid,$rcd[id],$rcd[loc],$rcd[len
]);
    }
    
fseek($this->dbh,$rcd[loc
]);
    
fwrite($this->dbh,$newcontent,$len
);
    
//echo $id.'<br>'.$content.'<br>'.$len;
  
}
  function 
selectByRid($rid
)
  {
    
$res=array('id'=>0,'content'=>''
);
    if (
$rid<or $rid>$this->rcdCnt) return $res
;
    else 
$rcd=$this->getRcd($rid
);
    
$res[id]=$rcd[id
];
    
$res[len]=$rcd[len
];
    
fseek($this->dbh,$rcd[loc
]);
    
$res[content]=fread($this->dbh,$rcd[len
]);
    
//$res[rid]=$rid;
    
return $res
;
  }
  function 
select($id
)
  {
    return 
$this->selectByRid($this->findByID($id
));
  }
  function 
backup
()
  {
    
copy($this->path.'/'.$this->name.'.tdb',$this->path.'/'.$this->name.'.tdb.bck'
);
    
copy($this->path.'/'.$this->name.'.indx',$this->path.'/'.$this->name.'.indx.bck'
);
    
copy($this->path.'/'.$this->name.'.lft',$this->path.'/'.$this->name.'.lft.bck'
);
  }
  function 
recover
()
  {
    
copy($this->path.'/'.$this->name.'.tdb.bck',$this->path.'/'.$this->name.'.tdb'
);
    
copy($this->path.'/'.$this->name.'.indx.bck',$this->path.'/'.$this->name.'.indx'
);
    
copy($this->path.'/'.$this->name.'.lft.bck',$this->path.'/'.$this->name.'.lft'
);
  }
}

?>

相关文章推荐

文本数据库操作实例

  • 2015年06月11日 09:09
  • 475KB
  • 下载

自己写的一个PHP数据库操作类

  • 2014年09月08日 14:06
  • 2KB
  • 下载

B树与数据库的结合(很不错)

B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用。 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树: ⑴树中每个结点至多有m 棵子树; ⑵若...

从配置文件读取数据连接信息,利用泛型和java反射机制,写一个公共的增删改查数据库操作类

背景: 最近在学习java,然后就看了spring jdbc。对于菜鸟来说,看得实在头大,然而还有强迫症作祟最是要不得。又要导入common的相关jar包,又要导入mysql的jar包,还要导入spr...

c#开源的文本编辑器。很不错

  • 2011年05月16日 23:30
  • 1.86MB
  • 下载

一款很不错的文本编辑器

  • 2011年05月17日 17:27
  • 904KB
  • 下载

androd SQLite 自己写的数据库操作类

package com.db; import android.content.ContentValues; import android.content.Context; import ...

小说文本分割器 很不错的哦

  • 2009年03月27日 22:39
  • 141KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[转]某文本数据库blog作者写的文本数据库操作类,很不错
举报原因:
原因补充:

(最多只允许输入30个字)