{   This unit interfaces MySQL libs.
    Copyright (C) 2003 by Eike Lange
    Author: Eike Lange <eike@g-n-u.de>
    
    This unit is free software; you can redistribute it and/or modify
    it under the terms of the GNU Library General Public License as
    published by the Free Software Foundation, version 2.
     
    This unit is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Library General Public License for more details.
    
    You should have received a copy of the GNU Library General Public
    License along with this library; see the file COPYING.LIB. If not,
    write to the Free Software Foundation, Inc., 59 Temple Place -
    Suite 330, Boston, MA 02111-1307, USA. }

{$gnu-pascal,I-}
{$if __GPC_RELEASE__ < 20030303}
{$error This unit requires GPC release 20030303 or newer.}
{$endif}

unit MySQL;


interface

uses GPC;

type
  PMySQL = Pointer;
  PMySQLRes = Pointer;
  PMySQLField = ^MySQLField;
  PMySQLFieldArray = ^MySQLFieldArray;
  PMySQLRow = ^MySQLRow;

  MySQLField = record
    FieldName, Table, OrgTable, Db, Def: CString;
    ColumnLength, MaxLength: MedCard;
    Flags, Decimals: Cardinal;
    FieldType: Integer
  end;
  MySQLFieldArray = array [0 .. MaxVarSize div SizeOf (MySQLField)] of MySQLField;
  MySQLRow = array [0 .. MaxVarSize] of CString;

  { just for MySQLFetchLengths }
  PMedCardArray = ^MedCardArray;
  MedCardArray = array [0 .. MaxVarSize] of MedCard;

var
  { MySQLOption }
  MYSQL_OPT_CONNECT_TIMEOUT:Integer; external name 'p_MYSQL_OPT_CONNECT_TIMEOUT'; attribute (const);
  MYSQL_OPT_COMPRESS:       Integer; external name 'p_MYSQL_OPT_COMPRESS'; attribute (const);
  MYSQL_OPT_NAMED_PIPE:     Integer; external name 'p_MYSQL_OPT_NAMED_PIPE'; attribute (const);
  MYSQL_INIT_COMMAND:       Integer; external name 'p_MYSQL_INIT_COMMAND'; attribute (const);
  MYSQL_READ_DEFAULT_FILE:  Integer; external name 'p_MYSQL_READ_DEFAULT_FILE'; attribute (const);
  MYSQL_READ_DEFAULT_GROUP: Integer; external name 'p_MYSQL_READ_DEFAULT_GROUP'; attribute (const);
  MYSQL_SET_CHARSET_DIR:    Integer; external name 'p_MYSQL_SET_CHARSET_DIR'; attribute (const);
  MYSQL_SET_CHARSET_NAME:   Integer; external name 'p_MYSQL_SET_CHARSET_NAME'; attribute (const);
  MYSQL_OPT_LOCAL_INFILE:   Integer; external name 'p_MYSQL_OPT_LOCAL_INFILE'; attribute (const);

  { MySQLStatus }
  MYSQL_STATUS_READY:       Integer; external name 'p_MYSQL_STATUS_READY'; attribute (const);
  MYSQL_STATUS_GET_RESULT:  Integer; external name 'p_MYSQL_STATUS_GET_RESULT'; attribute (const);
  MYSQL_STATUS_USE_RESULT:  Integer; external name 'p_MYSQL_STATUS_USE_RESULT'; attribute (const);

  { Misc }
  MAX_MYSQL_MANAGER_ERR:    Integer; external name 'p_MAX_MYSQL_MANAGER_ERR'; attribute (const);
  MAX_MYSQL_MANAGER_MSG:    Integer; external name 'p_MAX_MYSQL_MANAGER_MSG'; attribute (const);
  MANAGER_OK:               Integer; external name 'p_MANAGER_OK'; attribute (const);
  MANAGER_INFO:             Integer; external name 'p_MANAGER_INFO'; attribute (const);
  MANAGER_ACCESS:           Integer; external name 'p_MANAGER_ACCESS'; attribute (const);
  MANAGER_CLIENT_ERR:       Integer; external name 'p_MANAGER_CLIENT_ERR'; attribute (const);
  MANAGER_INTERNAL_ERR:     Integer; external name 'p_MANAGER_INTERNAL_ERR'; attribute (const);

  { Error Messages }
  CR_MIN_ERROR:           Integer; external name '_p_CR_MIN_ERROR'; attribute (const);
  CR_MAX_ERROR:           Integer; external name '_p_CR_MAX_ERROR'; attribute (const);
  CR_UNKNOWN_ERROR:       Integer; external name '_p_CR_UNKNOWN_ERROR'; attribute (const);
  CR_SOCKET_CREATE_ERROR: Integer; external name '_p_CR_SOCKET_CREATE_ERROR'; attribute (const);
  CR_CONNECTION_ERROR:    Integer; external name '_p_CR_CONNECTION_ERROR'; attribute (const);
  CR_CONN_HOST_ERROR:     Integer; external name '_p_CR_CONN_HOST_ERROR'; attribute (const);
  CR_IPSOCK_ERROR:        Integer; external name '_p_CR_IPSOCK_ERROR'; attribute (const);
  CR_UNKNOWN_HOST:        Integer; external name '_p_CR_UNKNOWN_HOST'; attribute (const);
  CR_SERVER_GONE_ERROR:   Integer; external name '_p_CR_SERVER_GONE_ERROR'; attribute (const);
  CR_VERSION_ERROR:       Integer; external name '_p_CR_VERSION_ERROR'; attribute (const);
  CR_OUT_OF_MEMORY:       Integer; external name '_p_CR_OUT_OF_MEMORY'; attribute (const);
  CR_WRONG_HOST_INFO:     Integer; external name '_p_CR_WRONG_HOST_INFO'; attribute (const);
  CR_LOCALHOST_CONNECTION:Integer; external name '_p_CR_LOCALHOST_CONNECTION'; attribute (const);
  CR_TCP_CONNECTION:      Integer; external name '_p_CR_TCP_CONNECTION'; attribute (const);
  CR_SERVER_HANDSHAKE_ERR:Integer; external name '_p_CR_SERVER_HANDSHAKE_ERR'; attribute (const);
  CR_SERVER_LOST:         Integer; external name '_p_CR_SERVER_LOST'; attribute (const);
  CR_COMMANDS_OUT_OF_SYNC:Integer; external name '_p_CR_COMMANDS_OUT_OF_SYNC'; attribute (const);
  CR_NAMEDPIPE_CONNECTION:Integer; external name '_p_CR_NAMEDPIPE_CONNECTION'; attribute (const);
  CR_NAMEDPIPEWAIT_ERROR: Integer; external name '_p_CR_NAMEDPIPEWAIT_ERROR'; attribute (const);
  CR_NAMEDPIPEOPEN_ERROR: Integer; external name '_p_CR_NAMEDPIPEOPEN_ERROR'; attribute (const);
  CR_NAMEDPIPESETSTATE_ERROR: Integer; external name '_p_CR_NAMEDPIPESETSTATE_ERROR'; attribute (const);
  CR_CANT_READ_CHARSET:   Integer; external name '_p_CR_CANT_READ_CHARSET'; attribute (const);
  CR_NET_PACKET_TOO_LARGE:Integer; external name '_p_CR_NET_PACKET_TOO_LARGE'; attribute (const);
  CR_EMBEDDED_CONNECTION: Integer; external name '_p_CR_EMBEDDED_CONNECTION'; attribute (const);
  CR_PROBE_SLAVE_STATUS:  Integer; external name '_p_CR_PROBE_SLAVE_STATUS'; attribute (const);
  CR_PROBE_SLAVE_HOSTS:   Integer; external name '_p_CR_PROBE_SLAVE_HOSTS'; attribute (const);
  CR_PROBE_SLAVE_CONNECT: Integer; external name '_p_CR_PROBE_SLAVE_CONNECT'; attribute (const);
  CR_PROBE_MASTER_CONNECT: Integer; external name '_p_CR_PROBE_MASTER_CONNECT'; attribute (const);
  CR_SSL_CONNECTION_ERROR: Integer; external name '_p_CR_SSL_CONNECTION_ERROR'; attribute (const);
  CR_MALFORMED_PACKET:    Integer; external name '_p_CR_MALFORMED_PACKET'; attribute (const);


{@section Alphabetic Function List}

  { Number of Rows changed by last UPDATE, DELETE, INSERT - statement }
function MySQLAffectedRows (Handle: PMySQL): LongCard; external name 'mysql_affected_rows';
  { Changes user and sets default database to db (which can be nil).
    The C interface uses the return value to indicate, which error
    occured but you should use MySQLError in case of FALSE }
function MySQLChangeUser (Handle: PMySQL; User, Passwd, Db: CString): Boolean;
  { Returns the default character set name }
function MySQLCharacterSetName (Handle: PMySQL): TString;
  { closes an opened connection }
procedure MySQLClose (Handle: PMySQL); external name 'mysql_close';
  { Seeks to an arbitrary row in the range [0..MySQLNumRows-1].
    This routine should onle be used in conjunction with MySQLStoreResult }
procedure MySQLDataSeek (Res: PMySQLRes; Offset: LongCard); external name 'mysql_data_seek';
  { Please read the mysql reference manual before you use this function! }
procedure MySQLDebug (const Dbg: CString); external name 'mysql_debug';
  { Write debug info to server log, 0 indicates success }
function MySQLDumpDebugInfo (Handle: PMySQL): Integer; external name 'mysql_dump_debug_info';
  { returns a code for most recent error. 0 if no error }
function MySQLErrno (Handle: PMySQL): Cardinal; external name 'mysql_errno';
  { returns an error description }
function MySQLError (Handle: PMySQL): TString;
  { returns the definition of one column }
function MySQLFetchField (Res: PMySQLRes): PMySQLField; external name 'mysql_fetch_field';
  { returns an array of all columns }
function MySQLFetchFields (Res: PMySQLRes): PMySQLFieldArray; external name 'mysql_fetch_fields';
  { returns specified column. FieldNr is in the range 0...MySQLNumFields-1 }
function MySQLFetchFieldDirect (Res: PMySQLRes; FieldNr: Cardinal): PMySQLField; external name 'mysql_fetch_field_direct';
  {@@(untested) Returns an array of all columns of the current row }
function MySQLFetchLengths (Res: PMySQLRes): PMedCardArray; external name 'mysql_fetch_lengths';
  { retrives the next row. A row is just an array of CStrings, so you have
    to access them by e. g. Row^[i] }
function MySQLFetchRow (Res: PMySQLRes): PMySQLRow; external name 'mysql_fetch_row';
  { returns the number of columns for the most recent query }
function MySQLFieldCount (Res: PMySQLRes): Cardinal; external name 'mysql_field_count';
  { Sets the field cursor to given offset, returns previous position }
function MySQLFieldSeek (Res: PMySQLRes; Offset: Cardinal): Cardinal; external name 'mysql_field_seek';
  { returns the position of the field cursor }
function MySQLFieldTell (Res: PMySQLRes): Cardinal; external name 'mysql_field_tell';
  { Frees the memory allocated by MySQLStoreResult, MySQLUseResult, ... }
procedure MySQLFreeResult (Res: PMySQLRes); external name 'mysql_free_result';
  { String that represents client library version }
function MySQLGetClientInfo: TString;
  { returns string describing type of connection }
function MySQLGetHostInfo (Handle: PMySQL): TString;
  { Returns protocol version used by current connection }
function MySQLGetProtoInfo (Handle: PMySQL): Cardinal; external name 'mysql_get_proto_info';
  { returns string that represents server version number }
function MySQLGetServerInfo (Handle: PMySQL): TString;
  { Informations about most recent executed query }
function MySQLInfo (Handle: PMySQL): TString;
  { Initializes PMySQL object }
function MySQLInit (Handle: PMySQL): PMySQL; external name 'mysql_init';
  { Returns ID generated for AUTO_INCREMENT column }
function MySQLInsertID (Handle: PMySQL): LongCard; external name 'mysql_insert_id';
  { Tries to kill mysql thread given by PID, returns error code or 0 }
function MySQLKill (Handle: PMySQL; PID: Cardinal): Integer; external name 'mysql_kill';
  { Lists all databases given by wildcard }
function MySQLListDbs (Handle: PMySQL; const Wild: CString): PMySQLRes; external name 'mysql_list_dbs';
  { SHOW COLUMNS FROM Table LIKE Wild }
function MySQLListFields (Handle: PMySQL; const Table, Wild: CString): PMySQLRes; external name 'mysql_list_fields';
  { Lists current server threads }
function MySQLListProcesses (Handle: PMySQL): PMySQLRes; external name 'mysql_list_processes';
  { SHOW Tables LIKE Wild }
function MySQLListTables (Handle: PMySQL; const Wild: CString): PMySQLRes; external name 'mysql_list_tables';
  { returns the number of columns in a result }
function MySQLNumFields (Res: PMySQLRes): Cardinal; external name 'mysql_num_fields';
  { returns number of rows in a result }
function MySQLNumRows (Res: PMySQLRes): LongCard; external name 'mysql_num_rows';
  { sets extra connect options. Opt is MySQLOption above}
function MySQLOptions (Handle: PMySQL; Opt: Integer; Arg: Pointer): Boolean;
  { Checks server, 0 for success }
function MySQLPing (Handle: PMySQL): Integer; external name 'mysql_ping';
  { Executes a query. For queries containing binary data, use
    MySQLRealQuery instead }
function MySQLQuery (Handle: PMySQL; const Query: CString): Boolean;
  { connects to a MySQL database engine }
function MySQLRealConnect (Handle: PMySQL; const Host, User, Passwd, Db: CString;
  Port: Cardinal; const UnixSocket: CString; ClientFlag: Cardinal): PMySQL; external name 'mysql_real_connect';
  { creates legal SQL string }
function MySQLRealEscapeString (Handle: PMySQL; ToStr: CString; const FromStr: CString;
  aLength: Cardinal): Cardinal; external name 'mysql_real_escape_string';
  { Executes a query }
function MySQLRealQuery (Handle: PMySQL; const Query: CString; aLength: Cardinal): Boolean;
  { Sets row cursor to given offset. Use with MySQLStoreResult only! }
function MySQLRowSeek (Res: PMySQLRes; Offset: Cardinal): Cardinal; external name 'mysql_row_seek';
  { Returns current offset of row cursor }
function MySQLRowTell (Res: PMySQLRes): Cardinal; external name 'mysql_row_tell';
  { Sets current database }
function MySQLSelectDB (Handle: PMySQL; const Db: CString): Boolean;
  { Tries to shut down the server }
function MySQLShutdown (Handle: PMySQL): Boolean;
  { Server Status }
function MySQLStat (Handle: PMySQL): TString;
  { You MUST call MySQLStoreResult or MySQLUseResult for every
    query that successfully retrieves data (SELECT, SHOW, DESCRIBE, EXPLAIN }
function MySQLStoreResult (Handle: PMySQL): PMySQLRes; external name 'mysql_store_result';
function MySQLUseResult (Handle: PMySQL): PMySQLRes; external name 'mysql_use_result';


{@section Thread Routines}


  { Set up and bring down a thread; these function should be called
    for each thread in an application which opens at least one MySQL
    connection.  All uses of the connection(s) should be between these
    function calls. }
procedure MySQLThreadInit; external name 'mysql_thread_init';
procedure MySQLThreadEnd; external name 'mysql_thread_end';
function MySQLThreadID (Handle: PMySQL): Cardinal; external name 'mysql_thread_id';
  { TRUE, if client is thread safe }
function MySQLThreadSafe: Boolean;

implementation
{$L mysqlc.c, mysqlclient}

function CMySQLChangeUser (Handle: PMySQL; User, Passwd, Db: CString): Byte; external name 'mysql_change_user';
function MySQLChangeUser (Handle: PMySQL; User, Passwd, Db: CString): Boolean;
begin
  MySQLChangeUser := CMySQLChangeUser (Handle, User, Passwd, Db) = 0
end;

function CMySQLCharacterSetName (Handle: PMySQL): CString; external name 'mysql_character_set_name';
function MySQLCharacterSetName (Handle: PMySQL): TString;
begin
  MySQLCharacterSetName := CString2String (CMySQLCharacterSetName (Handle))
end;

function CMySQLError (Handle: PMySQL): CString; external name 'mysql_error';
function MySQLError (Handle: PMySQL): TString;
begin
  MySQLError := CString2String (CMySQLError (Handle))
end;

function CMySQLGetClientInfo: CString; external name 'mysql_get_client_info';
function MySQLGetClientInfo: TString;
begin
  MySQLGetClientInfo := CString2String (CMySQLGetClientInfo)
end;

function CMySQLGetHostInfo (Handle: PMySQL): TString; external name 'mysql_get_host_info';
function MySQLGetHostInfo (Handle: PMySQL): TString;
begin
  MySQLGetHostInfo := CString2String (CMySQLGetHostInfo (Handle))
end;

function CMySQLGetServerInfo (Handle: PMySQL): CString; external name 'mysql_get_server_info';
function MySQLGetServerInfo (Handle: PMySQL): TString;
begin
  MySQLGetServerInfo := CString2String (CMySQLGetServerInfo (Handle))
end;

function CMySQLInfo (Handle: PMySQL): CString; external name 'mysql_info';
function MySQLInfo (Handle: PMySQL): TString;
begin
  MySQLInfo := CString2String (CMySQLInfo (Handle))
end;

function CMySQLOptions (Handle: PMySQL; Opt: Integer; Arg: Pointer): Integer; external name 'mysql_options';
function MySQLOptions (Handle: PMySQL; Opt: Integer; Arg: Pointer): Boolean;
begin
  MySQLOptions := CMySQLOptions (Handle, Opt, Arg) = 0
end;

function CMySQLQuery (Handle: PMySQL; const Query: CString): Integer; external name 'mysql_query';
function MySQLQuery (Handle: PMySQL; const Query: CString): Boolean;
begin
  MySQLQuery := CMySQLQuery (Handle, Query) = 0
end;

function CMySQLRealQuery (Handle: PMySQL; const Query: CString; aLength: Cardinal): Integer; external name 'mysql_real_query';
function MySQLRealQuery (Handle: PMySQL; const Query: CString; aLength: Cardinal): Boolean;
begin
  MySQLRealQuery := CMySQLRealQuery (Handle, Query, aLength) = 0
end;

function CMySQLSelectDB (Handle: PMySQL; const Db: CString): Integer; external name 'mysql_select_db';
function MySQLSelectDB (Handle: PMySQL; const Db:  CString): Boolean;
begin
  MySQLSelectDB := CMySQLSelectDB (Handle, Db) = 0
end;

function CMySQLShutdown (Handle: PMySQL): Integer; external name 'mysql_shutdown';
function MySQLShutdown (Handle: PMySQL): Boolean;
begin
  MySQLShutdown := CMySQLShutdown (Handle) = 0
end;

function CMySQLStat (Handle: PMySQL): CString; external name 'mysql_stat';
function MySQLStat (Handle: PMySQL): TString;
begin
  MySQLStat := CString2String (CMySQLStat (Handle))
end;





function CMySQLThreadSafe: Cardinal; external name 'mysql_thread_safe';
function MySQLThreadSafe: Boolean;
begin
  MySQLThreadSafe := CMySQLThreadSafe = 1
end;


end.
