星星博客's Archiver

cnangel 发表于 2005-8-25 19:11

尝试用sql查询语句操纵普通文本数据库

[color=red]作者:Aren.Liu
日期:2000-12-27 9:00:24[/color]
尝试用sql查询语句操纵普通文本数据库!使用简单的select就可以实现文本的索引访问,用update……
[code]
use lib "."; # If NT,use lib "path-to-jtdb_directory";
use JTDB "1.01";
$main::split = ","; # Notice!, It';s necessary! must be $main::split,
# Records split by ","
my &#36;db = "<path-to>/dbname";
@main::recordNames = &db_connect(&#36;db); &#35; Necessary! must be @main::recordNames,
&#35; Get RecordNames from db-info file
my &#36;sqlStr = "SELECT * FROM &#36;db";
my @resoult = &executeStr(&#36;sqlStr);
my &#36;line;
foreach &#36;line (@resoult)
{
my &#36;keys;
foreach &#36;keys (keys %&#36;line)
{
print &#36;keys." : ".&#36;line->{&#36;keys}." ";
}
print "<br>\n";
}
[/code]
---------------------------
用这样简单的方式操作文本数据,其实也不是难事儿,看看这个模块吧。。

http://ub4k91.chinaw3.com/download/jtdb.htm
JTDB v1.01
[code]
&#35;-------------------------------------------------------------------
package JTDB;
&#35; ----------------------------------------------------------------------
&#35; 程序名称:平面文本SQL查询模块,JTDB V1.01
&#35;
&#35; 作者:阿恩 (Aren.Liu) / 成都金想网络技术有限公司
&#35;
&#35; 电话:028-4290153
&#35;
&#35; 传呼:96968-223046
&#35;
&#35; 一妹:boyaren@sina.com
&#35;
&#35; 主叶:http://www.justake.com http://jtbbs.nt.souying.com
&#35;
&#35; -----------------------------------------------------------------------
&#35; 版权所有 成都金想网络技术有限公司 来趣山庄
&#35; Copyright (C) 2000 Justake.com, JinXiang Co.,Ltd. All Rights Reserved
&#35; -----------------------------------------------------------------------
&#35; V 1.01 2000/12/27
&#35; 实现 create_db功能
&#35; V 1.00 2000/12/26
&#35; 设想并实现平面文本数据库SQL查询最基本功能
&#35; 可实现 select,insert,delete,update 基本功能
&#35; ------------------------------------------- 请保留以上版权 ------------
require 5.002;
use strict;
use vars qw(@ISA @EXPORT &#36;VERSION);
use Exporter;
&#36;VERSION = ';1.01';;
&#36;main::txt = ".txt";
@ISA = qw(Exporter);
@EXPORT = qw
(
&db_connect
&create_db
&executeStr
&readtxtfile
&writetxtfile
);
&#35;------------------------------------------------
sub create_db
{
my (&#36;jtdb,&#36;recordNames) = @_;
my &#36;jtdb_info = &#36;jtdb."_info".&#36;main::txt;
my &#36;dbname = &#36;jtdb.&#36;main::txt;
&notify("数据库已经存在,请选择其他数据库,数据库创建失败!",1) if (-e &#36;dbname);
open (JTDB,">&#36;dbname");
close(JTDB);
open (JTDBINFO,">&#36;jtdb_info");
print JTDBINFO &#36;recordNames."\n";
close(JTDBINFO);
return (1);
}
&#35;------------------------------------------------
sub db_connect
{
&#35;my &#36;dbname = substr(&#36;_[0],0,length(&#36;_[0])-4);
my &#36;dbname = &#36;_[0];
&notify("不能找到数据库信息文件,数据库连接失败!",1) if (!(-e &#36;dbname."_info".&#36;main::txt));
my @jtdb_info = &readtxtfile(&#36;dbname."_info".&#36;main::txt);
chomp(@jtdb_info);
&notify("数据库信息文件已经损坏或丢失,连接数据库失败!",1) if (&#36;jtdb_info[0] eq "");
my @keys = split(/&#36;main::split/,&#36;jtdb_info[0]);
my &#36;key;
foreach &#36;key (@keys)
{
&#36;key =~ s/^\s+//g;
&#36;key =~ s/\s+&#36;//g;
}
return @keys;
}
&#35;------------------------------------------------
sub db_save
{
my (&#36;jtdb,@toSave) = @_;
my &#36;dbname = &#36;jtdb.&#36;main::txt;
my &#36;just = &#36;jtdb.".lock";
while(-f &#36;just)
{select(undef,undef,undef,0.1);} &#35;锁文件
open(LOCKFILE,">&#36;just");
open (FD,">&#36;dbname");
my &#36;line;
foreach &#36;line (@toSave)
{
foreach (@main::recordNames)
{
print FD &#36;line->{&#36;_}.&#36;main::split;
}
print FD "\n";
}
close(FD);
close(LOCKFILE);
unlink(&#36;just);
return (1);
}
&#35;------------------------------------------------
sub executeStr
{
my @sqlcmds;
my &#36;sqlcmd;
grep{/\s*(\S+)\s+(.*)/ and &#36;sqlcmd = lc(&#36;1);} @_;
if (&#36;sqlcmd eq "select")
{
grep{/\s*(SELECT)\s+(\S+\s*(\s*\,+?\s*\S+)*)\s+FROM\s+(\S+)((\s+WHERE\s+(.*)\s*)*)/i and &#36;sqlcmd = lc(&#36;1);@sqlcmds = (&#36;2,&#36;4,&#36;7);} @_;
&sql_select(@sqlcmds);
}
elsif (&#36;sqlcmd eq "insert")
{
grep{/\s*(INSERT)\s+INTO\s+(\S+)((\s+\((\s*\S+\s*(\s*\,+?\s*\S+)*\s*)+?\))*?)\s+VALUES\s*\((.*)\)\s*/i and &#36;sqlcmd = lc(&#36;1);@sqlcmds = (&#36;2,&#36;5,&#36;7);} @_;
&sql_insert(@sqlcmds);
}
elsif (&#36;sqlcmd eq "delete")
{
grep{/\s*(DELETE)\s+FROM\s+(\S+)\s+WHERE\s+(.*)\s*/i and &#36;sqlcmd = lc(&#36;1);@sqlcmds = (&#36;2,&#36;3);} @_;
&sql_delete(@sqlcmds);
  }
  elsif (&#36;sqlcmd eq "update")
  {
grep{/\s*(UPDATE)\s+(\S+)\s+SET\s+(.*)\s+WHERE\s+(.*)\s*/i and &#36;sqlcmd = lc(&#36;1);@sqlcmds = (&#36;2,&#36;3,&#36;4);} @_;
&sql_update(@sqlcmds);
   }
  else
  {&notify("你输入的数据库操作语句不正确,或目前的版本尚未支持,请检查!");}
}
&#35;------------------------------------------------
sub sql_update
{
my (&#36;jtdb,&#36;set,&#36;where) = @_;
my @resoult = &executeStr("SELECT * FROM &#36;jtdb");
if (&#36;where ne "")
{
my &#36;key = ';';;
foreach &#36;key (@main::recordNames)
{
&#36;where =~ s/&#36;key/\&#36;_->{';&#36;key';}/ig;
}
}else {&notify("你没有提供修改条件,请用 WHERE 语句提供!");}
if (&#36;set ne "")
{
my &#36;key = ';';;
foreach &#36;key (@main::recordNames)
{
&#36;set =~ s/&#36;key\s*\=\s*(\';+?|\"+?)(.*)(\';+?|\"+?)\s*(\,*?)/\&#36;_->{';&#36;key';}\=&#36;1&#36;2&#36;3\;/ig;
}
}else {&notify("你没有提供修改项目,请用 SET 语句提供!");}
foreach (@resoult)
{
if (ev&#97;l(&#36;where))
{
ev&#97;l(&#36;set);
}
}
&db_save(&#36;jtdb,@resoult);
return (1);
}
&#35;------------------------------------------------
sub sql_delete
{
my (&#36;jtdb,&#36;where) = @_;
my @resoult = &executeStr("SELECT * FROM &#36;jtdb");
if (&#36;where ne "")
{
my &#36;key = ';';;
foreach &#36;key (@main::recordNames)
{
&#36;where =~ s/&#36;key/\&#36;_->{';&#36;key';}/ig;
}
}else {&notify("你没有提供删除条件,请用 WHERE 语句提供!");}
my @return = grep(ev&#97;l(&#36;where)==0,@resoult);
&db_save(&#36;jtdb,@return);
&#35;my &#36;just = &#36;jtdb.".lock";
&#35;while(-f &#36;just)
&#35;{select(undef,undef,undef,0.1);} &#35;锁文件
&#35;open(LOCKFILE,">&#36;just");
&#35;open (FD,">&#36;jtdb");
&#35;my &#36;line;
&#35;foreach &#36;line (@return)
&#35;{
&#35;foreach (@main::recordNames)
&#35;{
&#35;print FD &#36;line->{&#36;_}.&#36;main::split;
&#35; }
&#35; print FD "\n";
&#35;}
&#35;close(FD);
&#35;close(LOCKFILE);
&#35;unlink(&#36;just);
return (1);
}
&#35;------------------------------------------------
sub sql_insert
{
my (&#36;jtdb,&#36;keys,&#36;values) = @_;
&notify("找不到要操作的数据库,操作失败!") if (!(-e &#36;jtdb));
my @values = split(/\,/,&#36;values);
my &#36;addLine;
if (&#36;keys ne "")
{
&#35;my @main::recordNames = split(/&#36;main::split/,&#36;main::recordNames);
my @keys = split(/\,/,&#36;keys);
my &#36;i;
my @addLine;
for (&#36;i=0;&#36;i<@main::recordNames ;&#36;i++)
{
my &#36;n;
for (&#36;n=0;&#36;n<@keys;&#36;n++)
{
if (&#36;keys[&#36;n] eq &#36;main::recordNames[&#36;i])
{
&#36;addLine[&#36;i] = &#36;values[&#36;n];
last;
}
}
}
&#36;addLine = join(&#36;main::split,@addLine);
}
else
{
&notify("你输入的语句有错误!如果不指定插入字段,VALUES 值必须和数据库字段相对应,并且数量相等。") if(@values != @main::recordNames);
&#36;addLine = join(&#36;main::split,@values);
  }
&writetxtfile(&#36;jtdb,&#36;addLine.&#36;main::split."\n");
return (1);
}
&#35;------------------------------------------------
sub sql_select
{
my (&#36;select,&#36;from,&#36;where) = @_;
if (&#36;where ne "")
{
&#35;my @keys = split(/&#36;main::split/,&#36;main::recordNames);
my &#36;key = ';';;
foreach &#36;key (@main::recordNames)
{
&#35;&#36;key =~ s/^\s+//g;
&#35;&#36;key =~ s/\s+&#36;//g;
&#36;where =~ s/&#36;key/\&#36;record->{';&#36;key';}/ig;
}
}else {&#36;where = 1}
my &#36;dbinfo = &dbHoH(&#36;from);
my (&#36;key,&#36;record,&#36;recordName,&#36;return)=(';';,';';,';';,[]);
foreach &#36;key (keys %&#36;dbinfo)
{
my &#36;record = &#36;dbinfo->{&#36;key};
my @select = split(/\,/,&#36;select);
@select = @main::recordNames if (&#36;select =~ /\s*\*\s*/);
my &#36;lineHash = {};
foreach &#36;recordName (@select)
{
&#36;recordName =~ s/^\s+//g;
&#36;recordName =~ s/\s+&#36;//g;
&#36;lineHash->{&#36;recordName} = &#36;record->{&#36;recordName} if (ev&#97;l(&#36;where));
}
push(@&#36;return, &#36;lineHash);
}
return @&#36;return; &#35;返回查询结果,存储在 &#36;return 中,Array of Array
}
&#35;------------------------------------------------
sub dbHoH &#35;得到数据结构 Hash of Hash
{
my &#36;jtdb = &#36;_[0].&#36;main::txt;
my @database = &readtxtfile(&#36;jtdb);
chomp(@database);
&#35;my &#36;main::recordNames = shift(@database); &#35;get @col_names at the first line of txt_db,shift it
&#35;my &#36;keys = &getKeys(&#36;main::recordNames);
my &#36;keys = &getKeys(@main::recordNames);
my (&#36;line,&#36;return) = (';';,{});
foreach &#36;line (@database)
{
my &#36;keysHash = &getRef(&#36;line,&#36;keys);
&#36;return->{&#36;keysHash->{id}} = &#36;keysHash;
}
return &#36;return;
}
&#35;------------------------------------------------
sub getKeys &#35;得到关键字,BOOK<Perl 5 Complete>(中文) page(226)
{
&#35;my &#36;line = &#36;_[0];
&#35;my @keys = split(/&#36;main::split/,&#36;line);
my @keys = @_;
my (&#36;key,&#36;return,&#36;i) = (';';,{},0);
foreach &#36;key (@keys)
{
&#35;&#36;key =~ s/^\s+//g;
&#35;&#36;key =~ s/\s+&#36;//g;
&#36;return->{&#36;i++} = &#36;key;
}
return &#36;return;
}
&#35;------------------------------------------------
sub getRef &#35;得到关键字对应元素,BOOK<Perl 5 Complete>(中文) page(227)
{
my (&#36;line,&#36;keys) = @_;
my (&#36;element,@elements) = @_;
my &#36;return = {};
my &#36;i;
@elements = split(/&#36;main::split/,&#36;line);
for (&#36;i=0;&#36;i<@elements ;&#36;i++)
{
&#36;element = &#36;elements[&#36;i];
&#36;element =~ s/^\s+//g;
&#36;element =~ s/\s+&#36;//g;
&#36;return->{&#36;keys->{&#36;i}}=&#36;element;
}
return &#36;return;
}
&#35;------------------------------------------------
sub readtxtfile
{
my &#36;just = &#36;_[0].".lock";
while(-f &#36;just)
{select(undef,undef,undef,0.1);}
open(LOCKFILE,">&#36;just");
open(READTXTFILE,"&#36;_[0]");
my @readtxtfile=<READTXTFILE>;
close(READTXTFILE);
close(LOCKFILE);
unlink(&#36;just);
return @readtxtfile;
}
&#35;------------------------------------------------
sub writetxtfile
{
my &#36;just = &#36;_[0].".lock";
while(-f &#36;just)
{select(undef,undef,undef,0.1);}
open(LOCKFILE,">&#36;just");
if (&#36;_[2] == 1)
{open (WRITETXTFILE,">&#36;_[0]");}
else{open (WRITETXTFILE,">>&#36;_[0]");}
print WRITETXTFILE &#36;_[1];
close(WRITETXTFILE);
close(LOCKFILE);
unlink(&#36;just);
return(1);
}
&#35;------------------------------------------------
sub notify
{
use CGI;
my &#36;query = new CGI;
print &#36;query->header() if (&#36;_[1] == 1);
print &#36;_[0];
exit;
}
&#35;------------------------------------------------
1;
__END__

=head1 NAME
JTDB -- A modules of control a txt-database width SQL-words
=head1 SYNOPSIS
use lib "."; &#35; If NT,use lib "path-to-jtdb_directory";
use JTDB "1.01";
&#36;main::split = ","; &#35; Notice!, It';s necessary! must be &#36;main::split,
&#35; Records split by ","
my &#36;db = "<path-to>/dbname";
@main::recordNames = &db_connect(&#36;db); &#35; Necessary! must be @main::recordNames,
&#35; Get RecordNames from db-info file
my &#36;sqlStr = "SELECT * FROM &#36;db";
my @resoult = &executeStr(&#36;sqlStr);
my &#36;line;
foreach &#36;line (@resoult)
{
my &#36;keys;
foreach &#36;keys (keys %&#36;line)
{
print &#36;keys." : ".&#36;line->{&#36;keys}."";
}
print "<br>\n";
}
=head1 DESCRIPTION
This modules, JTDB.pm, is a tool of control  txt-database  width  SQL-words.
For now,only SELECT,INSERT,DELETE,UPDATE can be used in this script,and It';s
very simple.
It is only  opening-words, and I think  some one will  make it fullness and
mightiness one day! So,you can modify it at will!    and I hope you tell us
the headway of this modules and share it width everybody.   at last, I hope
you do not remove my copyright,if u will...
Enjoy it!
=item db_connect
open dbname_info.txt and get @recordNames
=item executeStr
Execute sql-script,and return a Array of Array
my @resoult = &executeStr(&#36;sqlStr);
my &#36;line;
foreach &#36;line (@resoult)
{
print &#36;line->{';id';}."\n";
print &#36;line->{';name';}."\n";
}
=item create_db
usage:
my &#36;ids = "id,name,pass,lover"; &#35; Now,&#36;main::split = ","
&#35; If &#36;ids = "id||name||pass||lover" then &#36;main::split = "||"
my &#36;dbname = "jtdatabase";
create_db("<path-to>/".&#36;dbname,&#36;ids);
&#35; Then,<path-to>/jtdatabase.txt and <path-to>/jtdatabase_info.txt has been
&#35; created !
=head2 SQL-String
select id,name from &#36;db where id>6
select * from from &#36;db where name=~ m"Aren"i and email ne ""
notices: at the block of WHERE ,u can use a-short-perl-code !!
--------------------------------------------------------------
INSERT INTO &#36;db (id,name) values(2009,Aren)
insert into &#36;db values ( 2009,Aren,12345,mylover)
notices: do not use '; or " at values-list
insert into &#36;db values ( ';2009';,';Aren';,';12345';,';mylover';)
will set id="';2009';" and name="';Aren';" and ...
--------------------------------------------------------------
DELETE FROM &#36;db WHERE id =~ /J/
--------------------------------------------------------------
update &#36;db set name=';jack';,pass=\"123\",lover=';jack\"lover'; where id = 3

=head1 BUGS

Author Aren <boyaren@sina.com> http://www.justake.com
=cut
[/code]



页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.