Revert r3979, move imported mysql_* functions from TDBConnection to a global var scope. Fixes issue #2647. Also, move MySQL related structures out of dbconnection.pas into mysql_structures.pas and const.inc.

This commit is contained in:
Ansgar Becker
2011-12-24 08:10:41 +00:00
parent 5b60d7047e
commit 1a593a24b4
3 changed files with 320 additions and 320 deletions

View File

@@ -344,6 +344,10 @@ const
MSG_NOGRIDEDITING = 'Selected columns don''t contain a sufficient set of key columns to allow editing. Please select primary or unique key columns, or just all columns.';
SIdle = 'Idle.';
SUnsupported = 'Not supported by this server';
MsgSQLError: String = 'SQL Error (%d): %s';
MsgUnhandledNetType: String = 'Unhandled connection type (%d)';
MsgDisconnect: String = 'Connection to %s closed at %s';
MsgInvalidColumn: String = 'Column #%d not available. Query returned %d columns and %d rows.';
PKEY = 'PRIMARY';
KEY = 'KEY';
@@ -366,3 +370,88 @@ const
// A set of characters which need not to be quoted
IDENTCHARS = ['A'..'Z', 'a'..'z', '0'..'9', '_'];
// General declarations
MYSQL_ERRMSG_SIZE = 512;
SQLSTATE_LENGTH = 5;
SCRAMBLE_LENGTH = 20;
MYSQL_PORT = 3306;
LOCAL_HOST = 'localhost';
NAME_LEN = 64;
PROTOCOL_VERSION = 10;
FRM_VER = 6;
// Field's flags
NOT_NULL_FLAG = 1;
PRI_KEY_FLAG = 2;
UNIQUE_KEY_FLAG = 4;
MULTIPLE_KEY_FLAG = 8;
BLOB_FLAG = 16;
UNSIGNED_FLAG = 32;
ZEROFILL_FLAG = 64;
BINARY_FLAG = 128;
ENUM_FLAG = 256;
AUTO_INCREMENT_FLAG = 512;
TIMESTAMP_FLAG = 1024;
SET_FLAG = 2048;
NUM_FLAG = 32768;
PART_KEY_FLAG = 16384;
GROUP_FLAG = 32768;
UNIQUE_FLAG = 65536;
BINCMP_FLAG = 131072;
// Client connection options
CLIENT_LONG_PASSWORD = 1;
CLIENT_FOUND_ROWS = 2; // Found instead of affected rows
CLIENT_LONG_FLAG = 4;
CLIENT_CONNECT_WITH_DB = 8;
CLIENT_NO_SCHEMA = 16; // Don't allow database.table.column
CLIENT_COMPRESS = 32;
CLIENT_ODBC = 64;
CLIENT_LOCAL_FILES = 128;
CLIENT_IGNORE_SPACE = 256; // Ignore spaces before '('
CLIENT_PROTOCOL_41 = 512;
CLIENT_INTERACTIVE = 1024;
CLIENT_SSL = 2048; // Switch to SSL after handshake
CLIENT_IGNORE_SIGPIPE = 4096;
CLIENT_TRANSACTIONS = 8192;
CLIENT_RESERVED = 16384;
CLIENT_SECURE_CONNECTION = 32768;
CLIENT_MULTI_STATEMENTS = 65536;
CLIENT_MULTI_RESULTS = 131072;
CLIENT_SSL_VERIFY_SERVER_CERT = 67108864;
CLIENT_REMEMBER_OPTIONS = 134217728;
// Enum Field Types
FIELD_TYPE_DECIMAL = 0;
FIELD_TYPE_TINY = 1;
FIELD_TYPE_SHORT = 2;
FIELD_TYPE_LONG = 3;
FIELD_TYPE_FLOAT = 4;
FIELD_TYPE_DOUBLE = 5;
FIELD_TYPE_NULL = 6;
FIELD_TYPE_TIMESTAMP = 7;
FIELD_TYPE_LONGLONG = 8;
FIELD_TYPE_INT24 = 9;
FIELD_TYPE_DATE = 10;
FIELD_TYPE_TIME = 11;
FIELD_TYPE_DATETIME = 12;
FIELD_TYPE_YEAR = 13;
FIELD_TYPE_NEWDATE = 14;
FIELD_TYPE_VARCHAR = 15;
FIELD_TYPE_BIT = 16;
FIELD_TYPE_NEWDECIMAL = 246;
FIELD_TYPE_ENUM = 247;
FIELD_TYPE_SET = 248;
FIELD_TYPE_TINY_BLOB = 249;
FIELD_TYPE_MEDIUM_BLOB = 250;
FIELD_TYPE_LONG_BLOB = 251;
FIELD_TYPE_BLOB = 252;
FIELD_TYPE_VAR_STRING = 253;
FIELD_TYPE_STRING = 254;
FIELD_TYPE_GEOMETRY = 255;
COLLATION_BINARY = 63;
// Equivalent to COLLATION_BINARY, this is what a new driver returns when connected to a pre-4.1 server.
COLLATION_NONE = 0;

View File

@@ -8,175 +8,6 @@ uses
type
PUSED_MEM=^USED_MEM;
USED_MEM = packed record
next: PUSED_MEM;
left: Integer;
size: Integer;
end;
PERR_PROC = ^ERR_PROC;
ERR_PROC = procedure;
PMEM_ROOT = ^MEM_ROOT;
MEM_ROOT = packed record
free: PUSED_MEM;
used: PUSED_MEM;
pre_alloc: PUSED_MEM;
min_malloc: Integer;
block_size: Integer;
block_num: Integer;
first_block_usage: Integer;
error_handler: PERR_PROC;
end;
NET = record
vio: Pointer;
buff: PAnsiChar;
buff_end: PAnsiChar;
write_pos: PAnsiChar;
read_pos: PAnsiChar;
fd: Integer;
max_packet: Cardinal;
max_packet_size: Cardinal;
pkt_nr: Cardinal;
compress_pkt_nr: Cardinal;
write_timeout: Cardinal;
read_timeout: Cardinal;
retry_count: Cardinal;
fcntl: Integer;
compress: Byte;
remain_in_buf: LongInt;
length: LongInt;
buf_length: LongInt;
where_b: LongInt;
return_status: Pointer;
reading_or_writing: Char;
save_char: Char;
no_send_ok: Byte;
last_error: array[1..MYSQL_ERRMSG_SIZE] of Char;
sqlstate: array[1..SQLSTATE_LENGTH + 1] of Char;
last_errno: Cardinal;
error: Char;
query_cache_query: Pointer;
report_error: Byte;
return_errno: Byte;
end;
PMYSQL_FIELD = ^MYSQL_FIELD;
MYSQL_FIELD = record
name: PAnsiChar; // Name of column
org_name: PAnsiChar; // Original column name, if an alias
table: PAnsiChar; // Table of column if column was a field
org_table: PAnsiChar; // Org table name if table was an alias
db: PAnsiChar; // Database for table
catalog: PAnsiChar; // Catalog for table
def: PAnsiChar; // Default value (set by mysql_list_fields)
length: LongInt; // Width of column
max_length: LongInt; // Max width of selected set
name_length: Cardinal;
org_name_length: Cardinal;
table_length: Cardinal;
org_table_length: Cardinal;
db_length: Cardinal;
catalog_length: Cardinal;
def_length: Cardinal;
flags: Cardinal; // Div flags
decimals: Cardinal; // Number of decimals in field
charsetnr: Cardinal; // Character set
_type: Cardinal; // Type of field. Se mysql_com.h for types
end;
MYSQL_ROW = array[0..$ffff] of PAnsiChar;
PMYSQL_ROW = ^MYSQL_ROW;
PMYSQL_ROWS = ^MYSQL_ROWS;
MYSQL_ROWS = record
next: PMYSQL_ROWS;
data: PMYSQL_ROW;
end;
MYSQL_DATA = record
Rows: Int64;
Fields: Cardinal;
Data: PMYSQL_ROWS;
Alloc: MEM_ROOT;
end;
PMYSQL_DATA = ^MYSQL_DATA;
PMYSQL = ^MYSQL;
MYSQL = record
_net: NET;
connector_fd: Pointer;
host: PAnsiChar;
user: PAnsiChar;
passwd: PAnsiChar;
unix_socket: PAnsiChar;
server_version: PAnsiChar;
host_info: PAnsiChar;
info: PAnsiChar;
db: PAnsiChar;
charset: PAnsiChar;
fields: PMYSQL_FIELD;
field_alloc: MEM_ROOT;
affected_rows: Int64;
insert_id: Int64;
extra_info: Int64;
thread_id: LongInt;
packet_length: LongInt;
port: Cardinal;
client_flag: LongInt;
server_capabilities: LongInt;
protocol_version: Cardinal;
field_count: Cardinal;
server_status: Cardinal;
server_language: Cardinal;
warning_count: Cardinal;
options: Cardinal;
status: Byte;
free_me: Byte;
reconnect: Byte;
scramble: array[1..SCRAMBLE_LENGTH+1] of Char;
rpl_pivot: Byte;
master: PMYSQL;
next_slave: PMYSQL;
last_used_slave: PMYSQL;
last_used_con: PMYSQL;
stmts: Pointer;
methods: Pointer;
thd: Pointer;
unbuffered_fetch_owner: PByte;
end;
MYSQL_RES = record
row_count: Int64;
fields: PMYSQL_FIELD;
data: PMYSQL_DATA;
data_cursor: PMYSQL_ROWS;
lengths: PLongInt;
handle: PMYSQL;
field_alloc: MEM_ROOT;
field_count: Integer;
current_field: Integer;
row: PMYSQL_ROW;
current_row: PMYSQL_ROW;
eof: Byte;
unbuffered_fetch_cancelled: Byte;
methods: PAnsiChar;
end;
PMYSQL_RES = ^MYSQL_RES;
TMySQLOption = (MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH);
{ TDBObjectList and friends }
TListNodeType = (lntNone, lntDb, lntTable, lntView, lntFunction, lntProcedure, lntTrigger, lntEvent, lntColumn);
@@ -443,33 +274,6 @@ type
procedure SetObjectNamesInSelectedDB;
procedure SetLockedByThread(Value: TThread); virtual;
public
mysql_affected_rows: function(Handle: PMYSQL): Int64; stdcall;
mysql_character_set_name: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_close: procedure(Handle: PMYSQL); stdcall;
mysql_data_seek: procedure(Result: PMYSQL_RES; Offset: Int64); stdcall;
mysql_errno: function(Handle: PMYSQL): Cardinal; stdcall;
mysql_error: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_fetch_field_direct: function(Result: PMYSQL_RES; FieldNo: Cardinal): PMYSQL_FIELD; stdcall;
mysql_fetch_lengths: function(Result: PMYSQL_RES): PLongInt; stdcall;
mysql_fetch_row: function(Result: PMYSQL_RES): PMYSQL_ROW; stdcall;
mysql_free_result: procedure(Result: PMYSQL_RES); stdcall;
mysql_get_client_info: function: PAnsiChar; stdcall;
mysql_get_server_info: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_init: function(Handle: PMYSQL): PMYSQL; stdcall;
mysql_num_fields: function(Result: PMYSQL_RES): Integer; stdcall;
mysql_num_rows: function(Result: PMYSQL_RES): Int64; stdcall;
mysql_options: function(Handle: PMYSQL; Option: TMySQLOption; arg: PAnsiChar): Integer; stdcall;
mysql_ping: function(Handle: PMYSQL): Integer; stdcall;
mysql_real_connect: function(Handle: PMYSQL; const Host, User, Passwd, Db: PAnsiChar; Port: Cardinal; const UnixSocket: PAnsiChar; ClientFlag: Cardinal): PMYSQL; stdcall;
mysql_real_query: function(Handle: PMYSQL; const Query: PAnsiChar; Length: Cardinal): Integer; stdcall;
mysql_ssl_set: function(Handle: PMYSQL; const key, cert, CA, CApath, cipher: PAnsiChar): Byte; stdcall;
mysql_stat: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_store_result: function(Handle: PMYSQL): PMYSQL_RES; stdcall;
mysql_thread_id: function(Handle: PMYSQL): Cardinal; stdcall;
mysql_next_result: function(Handle: PMYSQL): Integer; stdcall;
mysql_set_character_set: function(Handle: PMYSQL; csname: PAnsiChar): Integer; stdcall;
mysql_thread_init: function: Byte; stdcall;
mysql_thread_end: procedure; stdcall;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Query(SQL: String; DoStoreResult: Boolean=False; LogCategory: TDBLogCategory=lcSQL); virtual; abstract;
@@ -551,8 +355,6 @@ type
TMySQLConnection = class(TDBConnection)
private
FHandle: PMYSQL;
FLibraryHandle: HMODULE;
FLibraryPath: String;
FLastRawResults: TMySQLRawResults;
FPlinkProcInfo: TProcessInformation;
procedure SetActive(Value: Boolean); override;
@@ -572,7 +374,6 @@ type
procedure SetLockedByThread(Value: TThread); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Query(SQL: String; DoStoreResult: Boolean=False; LogCategory: TDBLogCategory=lcSQL); override;
function ConvertServerVersion(Version: Integer): String; override;
function Ping(Reconnect: Boolean): Boolean; override;
@@ -740,11 +541,39 @@ function mysql_authentication_dialog_ask(
exports
mysql_authentication_dialog_ask;
const
MsgSQLError: String = 'SQL Error (%d): %s';
MsgUnhandledNetType: String = 'Unhandled connection type (%d)';
MsgDisconnect: String = 'Connection to %s closed at %s';
MsgInvalidColumn: String = 'Column #%d not available. Query returned %d columns and %d rows.';
{$I const.inc}
var
LibMysqlPath: String = 'libmysql.dll';
LibMysqlHandle: HMODULE; // Shared module handle
mysql_affected_rows: function(Handle: PMYSQL): Int64; stdcall;
mysql_character_set_name: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_close: procedure(Handle: PMYSQL); stdcall;
mysql_data_seek: procedure(Result: PMYSQL_RES; Offset: Int64); stdcall;
mysql_errno: function(Handle: PMYSQL): Cardinal; stdcall;
mysql_error: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_fetch_field_direct: function(Result: PMYSQL_RES; FieldNo: Cardinal): PMYSQL_FIELD; stdcall;
mysql_fetch_lengths: function(Result: PMYSQL_RES): PLongInt; stdcall;
mysql_fetch_row: function(Result: PMYSQL_RES): PMYSQL_ROW; stdcall;
mysql_free_result: procedure(Result: PMYSQL_RES); stdcall;
mysql_get_client_info: function: PAnsiChar; stdcall;
mysql_get_server_info: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_init: function(Handle: PMYSQL): PMYSQL; stdcall;
mysql_num_fields: function(Result: PMYSQL_RES): Integer; stdcall;
mysql_num_rows: function(Result: PMYSQL_RES): Int64; stdcall;
mysql_options: function(Handle: PMYSQL; Option: TMySQLOption; arg: PAnsiChar): Integer; stdcall;
mysql_ping: function(Handle: PMYSQL): Integer; stdcall;
mysql_real_connect: function(Handle: PMYSQL; const Host, User, Passwd, Db: PAnsiChar; Port: Cardinal; const UnixSocket: PAnsiChar; ClientFlag: Cardinal): PMYSQL; stdcall;
mysql_real_query: function(Handle: PMYSQL; const Query: PAnsiChar; Length: Cardinal): Integer; stdcall;
mysql_ssl_set: function(Handle: PMYSQL; const key, cert, CA, CApath, cipher: PAnsiChar): Byte; stdcall;
mysql_stat: function(Handle: PMYSQL): PAnsiChar; stdcall;
mysql_store_result: function(Handle: PMYSQL): PMYSQL_RES; stdcall;
mysql_thread_id: function(Handle: PMYSQL): Cardinal; stdcall;
mysql_next_result: function(Handle: PMYSQL): Integer; stdcall;
mysql_set_character_set: function(Handle: PMYSQL; csname: PAnsiChar): Integer; stdcall;
mysql_thread_init: function: Byte; stdcall;
mysql_thread_end: procedure; stdcall;
implementation
@@ -905,7 +734,6 @@ var
begin
inherited;
FQuoteChar := '`';
FLibraryPath := 'libmysql.dll';
// The compiler complains that dynamic and static arrays are incompatible, so this does not work:
// FDatatypes := MySQLDatatypes
SetLength(FDatatypes, Length(MySQLDatatypes));
@@ -944,16 +772,6 @@ begin
end;
destructor TMySQLConnection.Destroy;
begin
// Release libmysql.dll handle
inherited;
if FLibraryHandle <> 0 then
FreeLibrary(FLibraryHandle);
FLibraryHandle := 0;
end;
function TDBConnection.GetDatatypeByName(Datatype: String): TDBDatatype;
var
i: Integer;
@@ -971,10 +789,10 @@ procedure TMySQLConnection.AssignProc(var Proc: FARPROC; Name: PAnsiChar);
begin
// Map library procedure to internal procedure
Log(lcDebug, 'Assign procedure "'+Name+'"');
Proc := GetProcAddress(FLibraryHandle, Name);
Proc := GetProcAddress(LibMysqlHandle, Name);
if Proc = nil then begin
FLibraryHandle := 0;
raise EDatabaseError.Create('Your '+FLibraryPath+' is out-dated or somehow incompatible to '+APPNAME+'. Please use the one from the installer, or just reinstall '+APPNAME+'.');
LibMysqlHandle := 0;
raise EDatabaseError.Create('Your '+LibMysqlPath+' is out-dated or somehow incompatible to '+APPNAME+'. Please use the one from the installer, or just reinstall '+APPNAME+'.');
end;
end;
@@ -1292,11 +1110,11 @@ procedure TMySQLConnection.DoBeforeConnect;
begin
// Init libmysql before actually connecting.
// Each connection has its own library handle
if FLibraryHandle = 0 then begin
Log(lcDebug, 'Loading library file '+FLibraryPath+' ...');
FLibraryHandle := LoadLibrary(PWideChar(FLibraryPath));
if FLibraryHandle = 0 then
raise EDatabaseError.Create('Can''t find a usable '+FLibraryPath+'. Please launch '+ExtractFileName(ParamStr(0))+' from the directory where you have installed it.')
if LibMysqlHandle = 0 then begin
Log(lcDebug, 'Loading library file '+LibMysqlPath+' ...');
LibMysqlHandle := LoadLibrary(PWideChar(LibMysqlPath));
if LibMysqlHandle = 0 then
raise EDatabaseError.Create('Can''t find a usable '+LibMysqlPath+'. Please launch '+ExtractFileName(ParamStr(0))+' from the directory where you have installed it.')
else begin
AssignProc(@mysql_affected_rows, 'mysql_affected_rows');
AssignProc(@mysql_character_set_name, 'mysql_character_set_name');
@@ -1325,7 +1143,7 @@ begin
AssignProc(@mysql_set_character_set, 'mysql_set_character_set');
AssignProc(@mysql_thread_init, 'mysql_thread_init');
AssignProc(@mysql_thread_end, 'mysql_thread_end');
Log(lcDebug, FLibraryPath + ' v' + DecodeApiString(mysql_get_client_info) + ' loaded.');
Log(lcDebug, LibMysqlPath + ' v' + DecodeApiString(mysql_get_client_info) + ' loaded.');
end;
end;
inherited;
@@ -3299,7 +3117,7 @@ var
i: Integer;
begin
if HasResult then for i:=Low(FResultList) to High(FResultList) do
FConnection.mysql_free_result(FResultList[i]);
mysql_free_result(FResultList[i]);
SetLength(FResultList, 0);
inherited;
end;
@@ -3341,7 +3159,7 @@ begin
NumResults := Length(FResultList)+1
else begin
for i:=Low(FResultList) to High(FResultList) do
FConnection.mysql_free_result(FResultList[i]);
mysql_free_result(FResultList[i]);
NumResults := 1;
FRecordCount := 0;
FEditingPrepared := False;
@@ -3356,14 +3174,14 @@ begin
if HasResult then begin
// FCurrentResults is normally done in SetRecNo, but never if result has no rows
FCurrentResults := LastResult;
NumFields := FConnection.mysql_num_fields(LastResult);
NumFields := mysql_num_fields(LastResult);
SetLength(FColumnTypes, NumFields);
SetLength(FColumnLengths, NumFields);
SetLength(FColumnFlags, NumFields);
FColumnNames.Clear;
FColumnOrgNames.Clear;
for i:=0 to NumFields-1 do begin
Field := FConnection.mysql_fetch_field_direct(LastResult, i);
Field := mysql_fetch_field_direct(LastResult, i);
FColumnNames.Add(Connection.DecodeAPIString(Field.name));
if Connection.ServerVersionInt >= 40100 then
FColumnOrgNames.Add(Connection.DecodeAPIString(Field.org_name))
@@ -3573,11 +3391,11 @@ begin
// Do not seek if FCurrentRow points to the previous row of the wanted row
WantedLocalRecNo := FCurrentResults.row_count-(NumRows-Value);
if (WantedLocalRecNo = 0) or (FRecNo+1 <> Value) or (FCurrentRow = nil) then
FConnection.mysql_data_seek(FCurrentResults, WantedLocalRecNo);
FCurrentRow := FConnection.mysql_fetch_row(FCurrentResults);
mysql_data_seek(FCurrentResults, WantedLocalRecNo);
FCurrentRow := mysql_fetch_row(FCurrentResults);
FCurrentUpdateRow := nil;
// Remember length of column contents. Important for Col() so contents of cells with #0 chars are not cut off
LengthPointer := FConnection.mysql_fetch_lengths(FCurrentResults);
LengthPointer := mysql_fetch_lengths(FCurrentResults);
for j:=Low(FColumnLengths) to High(FColumnLengths) do
FColumnLengths[j] := PInteger(Integer(LengthPointer) + j * SizeOf(Integer))^;
break;
@@ -4248,7 +4066,7 @@ var
begin
// Return first available Field.db property, or just the current database as fallback
for i:=0 to ColumnCount-1 do begin
Field := FConnection.mysql_fetch_field_direct(FCurrentResults, i);
Field := mysql_fetch_field_direct(FCurrentResults, i);
if Field.db <> '' then begin
Result := Connection.DecodeAPIString(Field.db);
break;
@@ -4276,7 +4094,7 @@ var
begin
IsView := False;
for i:=0 to ColumnCount-1 do begin
Field := FConnection.mysql_fetch_field_direct(FCurrentResults, i);
Field := mysql_fetch_field_direct(FCurrentResults, i);
if Connection.DecodeAPIString(Field.table) <> Connection.DecodeAPIString(Field.org_table) then begin
// Probably a VIEW, in which case we rely on the first column's table name.
@@ -4804,4 +4622,16 @@ begin
end;
initialization
finalization
// Release libmysql.dll handle
if LibMysqlHandle <> 0 then begin
FreeLibrary(LibMysqlHandle);
LibMysqlHandle := 0;
end;
end.

View File

@@ -11,94 +11,175 @@ uses
{$I const.inc}
const
// General declarations
MYSQL_ERRMSG_SIZE = 512;
SQLSTATE_LENGTH = 5;
SCRAMBLE_LENGTH = 20;
MYSQL_PORT = 3306;
LOCAL_HOST = 'localhost';
NAME_LEN = 64;
PROTOCOL_VERSION = 10;
FRM_VER = 6;
// Field's flags
NOT_NULL_FLAG = 1;
PRI_KEY_FLAG = 2;
UNIQUE_KEY_FLAG = 4;
MULTIPLE_KEY_FLAG = 8;
BLOB_FLAG = 16;
UNSIGNED_FLAG = 32;
ZEROFILL_FLAG = 64;
BINARY_FLAG = 128;
ENUM_FLAG = 256;
AUTO_INCREMENT_FLAG = 512;
TIMESTAMP_FLAG = 1024;
SET_FLAG = 2048;
NUM_FLAG = 32768;
PART_KEY_FLAG = 16384;
GROUP_FLAG = 32768;
UNIQUE_FLAG = 65536;
BINCMP_FLAG = 131072;
// Client connection options
CLIENT_LONG_PASSWORD = 1;
CLIENT_FOUND_ROWS = 2; // Found instead of affected rows
CLIENT_LONG_FLAG = 4;
CLIENT_CONNECT_WITH_DB = 8;
CLIENT_NO_SCHEMA = 16; // Don't allow database.table.column
CLIENT_COMPRESS = 32;
CLIENT_ODBC = 64;
CLIENT_LOCAL_FILES = 128;
CLIENT_IGNORE_SPACE = 256; // Ignore spaces before '('
CLIENT_PROTOCOL_41 = 512;
CLIENT_INTERACTIVE = 1024;
CLIENT_SSL = 2048; // Switch to SSL after handshake
CLIENT_IGNORE_SIGPIPE = 4096;
CLIENT_TRANSACTIONS = 8192;
CLIENT_RESERVED = 16384;
CLIENT_SECURE_CONNECTION = 32768;
CLIENT_MULTI_STATEMENTS = 65536;
CLIENT_MULTI_RESULTS = 131072;
CLIENT_SSL_VERIFY_SERVER_CERT = 67108864;
CLIENT_REMEMBER_OPTIONS = 134217728;
// Enum Field Types
FIELD_TYPE_DECIMAL = 0;
FIELD_TYPE_TINY = 1;
FIELD_TYPE_SHORT = 2;
FIELD_TYPE_LONG = 3;
FIELD_TYPE_FLOAT = 4;
FIELD_TYPE_DOUBLE = 5;
FIELD_TYPE_NULL = 6;
FIELD_TYPE_TIMESTAMP = 7;
FIELD_TYPE_LONGLONG = 8;
FIELD_TYPE_INT24 = 9;
FIELD_TYPE_DATE = 10;
FIELD_TYPE_TIME = 11;
FIELD_TYPE_DATETIME = 12;
FIELD_TYPE_YEAR = 13;
FIELD_TYPE_NEWDATE = 14;
FIELD_TYPE_VARCHAR = 15;
FIELD_TYPE_BIT = 16;
FIELD_TYPE_NEWDECIMAL = 246;
FIELD_TYPE_ENUM = 247;
FIELD_TYPE_SET = 248;
FIELD_TYPE_TINY_BLOB = 249;
FIELD_TYPE_MEDIUM_BLOB = 250;
FIELD_TYPE_LONG_BLOB = 251;
FIELD_TYPE_BLOB = 252;
FIELD_TYPE_VAR_STRING = 253;
FIELD_TYPE_STRING = 254;
FIELD_TYPE_GEOMETRY = 255;
COLLATION_BINARY = 63;
// Equivalent to COLLATION_BINARY, this is what a new driver returns when connected to a pre-4.1 server.
COLLATION_NONE = 0;
type
PUSED_MEM=^USED_MEM;
USED_MEM = packed record
next: PUSED_MEM;
left: Integer;
size: Integer;
end;
PERR_PROC = ^ERR_PROC;
ERR_PROC = procedure;
PMEM_ROOT = ^MEM_ROOT;
MEM_ROOT = packed record
free: PUSED_MEM;
used: PUSED_MEM;
pre_alloc: PUSED_MEM;
min_malloc: Integer;
block_size: Integer;
block_num: Integer;
first_block_usage: Integer;
error_handler: PERR_PROC;
end;
NET = record
vio: Pointer;
buff: PAnsiChar;
buff_end: PAnsiChar;
write_pos: PAnsiChar;
read_pos: PAnsiChar;
fd: Integer;
max_packet: Cardinal;
max_packet_size: Cardinal;
pkt_nr: Cardinal;
compress_pkt_nr: Cardinal;
write_timeout: Cardinal;
read_timeout: Cardinal;
retry_count: Cardinal;
fcntl: Integer;
compress: Byte;
remain_in_buf: LongInt;
length: LongInt;
buf_length: LongInt;
where_b: LongInt;
return_status: Pointer;
reading_or_writing: Char;
save_char: Char;
no_send_ok: Byte;
last_error: array[1..MYSQL_ERRMSG_SIZE] of Char;
sqlstate: array[1..SQLSTATE_LENGTH + 1] of Char;
last_errno: Cardinal;
error: Char;
query_cache_query: Pointer;
report_error: Byte;
return_errno: Byte;
end;
PMYSQL_FIELD = ^MYSQL_FIELD;
MYSQL_FIELD = record
name: PAnsiChar; // Name of column
org_name: PAnsiChar; // Original column name, if an alias
table: PAnsiChar; // Table of column if column was a field
org_table: PAnsiChar; // Org table name if table was an alias
db: PAnsiChar; // Database for table
catalog: PAnsiChar; // Catalog for table
def: PAnsiChar; // Default value (set by mysql_list_fields)
length: LongInt; // Width of column
max_length: LongInt; // Max width of selected set
name_length: Cardinal;
org_name_length: Cardinal;
table_length: Cardinal;
org_table_length: Cardinal;
db_length: Cardinal;
catalog_length: Cardinal;
def_length: Cardinal;
flags: Cardinal; // Div flags
decimals: Cardinal; // Number of decimals in field
charsetnr: Cardinal; // Character set
_type: Cardinal; // Type of field. Se mysql_com.h for types
end;
MYSQL_ROW = array[0..$ffff] of PAnsiChar;
PMYSQL_ROW = ^MYSQL_ROW;
PMYSQL_ROWS = ^MYSQL_ROWS;
MYSQL_ROWS = record
next: PMYSQL_ROWS;
data: PMYSQL_ROW;
end;
MYSQL_DATA = record
Rows: Int64;
Fields: Cardinal;
Data: PMYSQL_ROWS;
Alloc: MEM_ROOT;
end;
PMYSQL_DATA = ^MYSQL_DATA;
PMYSQL = ^MYSQL;
MYSQL = record
_net: NET;
connector_fd: Pointer;
host: PAnsiChar;
user: PAnsiChar;
passwd: PAnsiChar;
unix_socket: PAnsiChar;
server_version: PAnsiChar;
host_info: PAnsiChar;
info: PAnsiChar;
db: PAnsiChar;
charset: PAnsiChar;
fields: PMYSQL_FIELD;
field_alloc: MEM_ROOT;
affected_rows: Int64;
insert_id: Int64;
extra_info: Int64;
thread_id: LongInt;
packet_length: LongInt;
port: Cardinal;
client_flag: LongInt;
server_capabilities: LongInt;
protocol_version: Cardinal;
field_count: Cardinal;
server_status: Cardinal;
server_language: Cardinal;
warning_count: Cardinal;
options: Cardinal;
status: Byte;
free_me: Byte;
reconnect: Byte;
scramble: array[1..SCRAMBLE_LENGTH+1] of Char;
rpl_pivot: Byte;
master: PMYSQL;
next_slave: PMYSQL;
last_used_slave: PMYSQL;
last_used_con: PMYSQL;
stmts: Pointer;
methods: Pointer;
thd: Pointer;
unbuffered_fetch_owner: PByte;
end;
MYSQL_RES = record
row_count: Int64;
fields: PMYSQL_FIELD;
data: PMYSQL_DATA;
data_cursor: PMYSQL_ROWS;
lengths: PLongInt;
handle: PMYSQL;
field_alloc: MEM_ROOT;
field_count: Integer;
current_field: Integer;
row: PMYSQL_ROW;
current_row: PMYSQL_ROW;
eof: Byte;
unbuffered_fetch_cancelled: Byte;
methods: PAnsiChar;
end;
PMYSQL_RES = ^MYSQL_RES;
TMySQLOption = (MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH);
// MySQL data types
TDBDatatypeIndex = (dtTinyint, dtSmallint, dtMediumint, dtInt, dtBigint,
dtFloat, dtDouble, dtDecimal, dtNumeric, dtReal, dtMoney, dtSmallmoney,