发挥你的想象,自己做一个数据库引擎?(15分)

  • 主题发起人 主题发起人 腾龙
  • 开始时间 开始时间

腾龙

Unregistered / Unconfirmed
GUEST, unregistred user!
欢迎大家谈谈要是自己做一个数据库引擎,就像ACCESS那样的,那该多爽呀。哈哈哈

虽然大家都是菜鸟,不过瞎想,没准会有好的火花呢。
 
tinydb就是。电子日记本作者郝新康做的。应该是C++ Builder开发的。
 

可以用odbc32.dll.自己做引擎。直接通过API函数访问数据库。下面代码是我在软件中
实现的一部分,可以参考,呵呵。

如果需要UODBC32.pas,可以和我联系。里面有所有odbc32.dll的函数。

procedure TForm1.Button1Click(Sender: TObject);
var
odbcrc: Integer;
henv: Integer;
hdbc: Integer;
hstmt: Integer;
iBufferLength: Integer;
iField1Value : SQLINTEGER; // 字段1的结果
pcField2Value: PCHAR; // 字段2的结果
begin

odbcrc := SQLAllocEnv(henv);
if (odbcrc=SQL_ERROR) then Raise Exception.Create('ODBC:SALAllocEnv------>Error');
odbcrc := SQLAllocConnect(henv, hdbc);
If ((odbcrc = SQL_ERROR) or (odbcrc=SQL_INVALID_HANDLE)) then begin
SQLFreeEnv(henv);
Raise Exception.Create('ODBC:SQLAllocConnect---------->Error');
end;
odbcrc := SQLConnect(hdbc, PChar(eSource.Text), Length(eSource.Text), PChar(eUser.Text), Length(eUser.Text), PChar(ePassword.Text), Length(ePassword.Text));
if Not ((odbcrc=SQL_SUCCESS) or (odbcrc=SQL_SUCCESS_WITH_INFO)) then begin
Raise Exception.Create('cannnot connect with ODBC:'+eSource.Text+',User:'+eUser.Text+',Password:'+ePassword.Text);
end;

odbcrc := SQLAllocStmt(hdbc, hstmt);
if ((odbcrc=SQL_ERROR) or (odbcrc=SQL_INVALID_HANDLE)) then begin
Raise Exception.Create('ODBC:SQLAllocStmt---------->Error');
end;

Memo1.Lines.Clear;
Memo1.Lines.Add('waiting........................');

odbcrc := SQLExecDirect(hstmt, PChar(eSQL.Text), SQL_NTS);
Memo1.Lines.Clear;
Memo1.Lines.Add(eSQL.Text);

if ((odbcrc=SQL_SUCCESS) or (odbcrc=SQL_SUCCESS_WITH_INFO)) then begin
Memo1.Lines.Add(' was executed successfully!!!');
Memo1.Lines.Add('--------------------------------------------------');
pcField2Value := AllocMem(100);
//*******************************************************************
// 对于HIESetFinanceFlag 程序来说,因为我们只要获得第一个记录的数据
// 所以,while (SQLFetch()) 可以改写为 if (SQLFetch())
//*******************************************************************
while (SQLFetch(hstmt)=SQL_SUCCESS) do begin
// 初试数据设置
iField1Value := -1;
//*******************************************************************
// 获得字段1 的整数结果
//*******************************************************************
SQLGetData(
hstmt,
1, SQL_INTEGER,
@iField1Value, sizeof(SQLINTEGER),
iBufferLength
);
//*******************************************************************
// 获得字段2 的字符串结果
//*******************************************************************
SQLGetData(
hstmt,
2, SQL_CHAR,
pcField2Value, 100,
iBufferLength
);
Memo1.Lines.Add(Format('%10d %s', [iField1Value,StrPas(pcField2Value)]));
end;
FreeMem(pcField2Value);
end else if (odbcrc=SQL_ERROR) then begin
Memo1.Lines.Add('Error happen while executing sql command above');
Memo1.Lines.Add(SQLGetSystemError(henv, hdbc, hstmt));
end;

SQLFreeStmt(hdbc, hstmt);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
end;


 
To yuanjj76
要:hezhiqun@ynto.net
顺便问一下,是不是通过这些函数依然是调用已经存在的数据库?(比如ACCESS)有没
有自己做一个数据库(包括库文件结构都完全是自己编写的)的相关资料?
 
我有点不明白,这样通过自己调用API做数据库引擎会比用ADO更好吗?
两者没有本质的区别啊
 
上面的是一部分,我们写数据库,用delphi写了一部分,C++写了大部分。
实现数据库一些功能,但还有SQL语句分析,和网络部分没写,最近很忙,可能空的时候再
完成,花了不少时间,我们取名叫九龙数据库。

做数据库引擎时,通过ODBC32.dll提供的函数实现的。相对比较简单点。
我就公开在这吧,希望对大家都有帮助。


unit UODBC32;
//****************************************************************************
// *
// * ODBC package.
// * www.labking.net
// *
//****************************************************************************
interface
//****************************************************************************
// SQL const definitions:
//****************************************************************************
const SQL_ERROR = -1;
const SQL_INVALID_HANDLE = -2;

const SQL_SUCCESS = 0;
const SQL_SUCCESS_WITH_INFO = 1;
const SQL_STILL_EXECUTING = 2;
const SQL_NEED_DATA = 99;

const SQL_NTS = -3;

//****************************************************************************
// SQL type definitions:
//****************************************************************************
const SQL_CHAR = 1;
const SQL_NUMERIC = 2;
const SQL_DECIMAL = 3;
const SQL_INTEGER = 4;
const SQL_SMALLINT = 5;
const SQL_FLOAT = 6;
const SQL_REAL = 7;
const SQL_DOUBLE = 8;

//****************************************************************************
// SQL function return type definitions:
//****************************************************************************
type SQLRETURN = smallint;
type SQLINTEGER= Integer;
type SQLSMALLINT=smallint;
type SQLCHAR = byte;
type PSQLCHAR = ^SQLCHAR;

function SQLAllocEnv(var hEnv: SQLINTEGER): SQLRETURN; stdcall;
function SQLAllocConnect(hEnv:SQLINTEGER; var hConnection: SQLINTEGER): SQLRETURN; stdcall;
function SQLConnect(
hCon: SQLINTEGER;
strServer: PChar; iServerNameLength: SQLINTEGER;
pcUserName: PChar; iUserNameLength: SQLINTEGER;
pcAuthentication: PChar; iAutherticationLength: SQLINTEGER): SQLRETURN; stdcall;

function SQLAllocStmt(hConnection: SQLINTEGER; var hStatement: SQLINTEGER): SQLRETURN; stdcall;
function SQLExecDirect(hStatement: SQLINTEGER; pcStatement: PChar; iLength: LongInt): SQLRETURN; stdcall;
function SQLExecute(hStatement: SQLINTEGER): SQLRETURN; stdcall;
function SQLGetData(
hStatement:SQLINTEGER;
iColumnNumber:SQLINTEGER; iTargetType: SQLINTEGER;
pTargetValue: Pointer; iBufferLength: SQLINTEGER;
var iStrLen_or_Ind: SQLINTEGER
): SQLRETURN; stdcall;

function SQLFreeConnect(hConnection: SQLINTEGER): SQLRETURN; stdcall;
function SQLDisconnect(hConnection: SQLINTEGER): SQLRETURN; stdcall;
function SQLFreeEnv(hEnvironment: SQLINTEGER): SQLRETURN; stdcall;
function SQLFreeHandle(iHandleType: SQLINTEGER; iHandle: SQLINTEGER): SQLRETURN; stdcall;
function SQLFreeStmt(hStatement: SQLINTEGER; iOption: SQLINTEGER): SQLRETURN; stdcall;


function SQLFetch(hStatement: SQLINTEGER): SQLRETURN; stdcall;
//*************************************************************************
// 动态结果数据集访问
//*************************************************************************
function SQLNumResultCols(hStatement: SQLINTEGER; var iColumnCount :SQLSMALLINT):SQLRETURN; stdcall;
function SQLRowCount(hStatement: SQLINTEGER; var iColumnCount :SQLSMALLINT):SQLRETURN; stdcall;

function SQLError(hEnviroment:SQLINTEGER; hConnection: SQLInteger; hStatement: SQLInteger;
pcState:PSQLCHAR; var iNativeError: SQLINTEGER; pcMessageBox: PSQLCHAR;
iBufferLength: SQLSMALLINT; var iTextLength: SQLSMALLINT): SQLRETURN; stdcall;
function SQLGetSystemError(hEnv, hDbc, hStmt: SQLInteger): String;


implementation
uses SysUtils;

const LIB_ODBC32 = 'ODBC32.DLL';

function SQLTables: SQLINTEGER; external LIB_ODBC32 name 'SQLTables';
function SQLAllocEnv; external LIB_ODBC32 name 'SQLAllocEnv';
function SQLAllocConnect; external LIB_ODBC32 name 'SQLAllocConnect';
function SQLConnect; external LIB_ODBC32 name 'SQLConnect';
function SQLDisconnect; external LIB_ODBC32 name 'SQLDisconnect';
function SQLFreeConnect; external LIB_ODBC32 name 'SQLFreeConnect';
function SQLAllocStmt; external LIB_ODBC32 name 'SQLAllocStmt';
function SQLExecDirect; external LIB_ODBC32 name 'SQLExecDirect';
function SQLExecute; external LIB_ODBC32 name 'SQLExecute';
function SQLFetch; external LIB_ODBC32 name 'SQLFetch';

function SQLFreeEnv; external LIB_ODBC32 name 'SQLFreeEnv';
function SQLFreeHandle; external LIB_ODBC32 name 'SQLFreeHandle';
function SQLFreeStmt; external LIB_ODBC32 name 'SQLFreeStmt';

function SQLGetData; external LIB_ODBC32 name 'SQLGetData';

function SQLNumResultCols; external LIB_ODBC32 name 'SQLNumResultCols';
function SQLRowCount; external LIB_ODBC32 name 'SQLRowCount';
function SQLError; external LIB_ODBC32 name 'SQLError';

function SQLGetSystemError(hEnv, hDbc, hStmt: SQLInteger): String;
var
MsgL: SQLSMALLINT;
NativeError: SQLINTEGER;
State: Array [0..255] of char;
Msg: Array [0..255] of char;
begin
SQLError (hEnv, hDbc, hStmt, @State, NativeError,
@Msg, 128, MsgL);
result := 'Error:'+IntToStr(NativeError)+#13+#10+
'State:'+StrPas(@State)+#13+#10+
'Message:'+StrPas(@Msg);
//SystemDebug.printf("***Error: %d: %s: %s/n", NativeError, State, Msg);
end;


end.
 
些数据库,构造文件结构并不是太难,关键是数据库定义、操纵实现的算法(也就是sql的支持)。
搜索引擎、安全、网络传送等问题十分南。
如果真有兴趣,从分析dbf出发(我以前做过),可以了界数据库的基本构造。
access很值得研究,就是ms一向少文档。

有控联系!
mike6912@sina.com
 
to 腾龙
dbf的数据库文件从前我研究过,很早了。
dbf的结构比较简单,一个文件头,定义了表的基本信息和纪录的结构,dbf中没有变长字符串,
每条纪录都占用相同的空间。。。
但数据库管理系统难点还是如我前面说的,那些算法要实现起来可不容易。
现在我还没有精力做这些事,最近我想研究一下解释器,如果成功了何许对你做数据库管理系统能有帮助。
 
接受答案了.
 
后退
顶部