Page 1 of 1

[bug_fixed] MySQL Embedded Server Arguments

Posted: 27.09.2006, 06:50
by tohenk
I’m using MySQL Embedded for some of my applications. I’ve tried ZEOSLIB ( rev 98 ) and it work fine. But, I need MySQL Embedded to be configurable via my app. In fact, ZEOSLIB doesn’t provide it. It only support simple ‘--datadir’ which defined in ZPlainMySQLConstants.pas. And it’s absolutely unconfigurable which always point to ./data/ relative to app path.

Figure it, I have connection properties like this:

Code: Select all

compress=yes
dbless=no
useresult=no
timeout=30
arg1=--basedir=./mysql
arg2=--datadir=./mysql/data
arg3=--character-sets-dir=./mysql/share/charsets
arg4=--language=./mysql/share/english
arg5=--skip-innodb
arg6=--key_buffer_size=32M
The most important things is, I need MySQL to be faster enough, like skipping innodb.
So I have modify MySQL library of ZEOSLIB.

1. ZPlainMySQLDriver.pas
a. Add uses clause of Classes

Before

Code: Select all

uses ZClasses, ...
After

Code: Select all

uses Classes, ZClasses, ...
b. Add procedure BuildOptions(Options: TStrings); of IZMySQLPlainDriver interface, insert after function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PChar; so it will like:

Code: Select all

function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PChar;
procedure BuildOptions(Options: TStrings);
c. Add procedure BuildOptions(Options: TStrings); declaration for each of derivated interface of IZMySQLPlainDriver.

Code: Select all

TZMySQL5PlainDriver = class (TZAbstractObject, IZPlainDriver,
  IZMySQLPlainDriver)
....
public
  ...
  procedure BuildOptions(Options: TStrings); virtual;
end;

TZMySQLD5PlainDriver = class (TZMySQL5PlainDriver)
public
  ...
  procedure BuildOptions(Options: TStrings); override;
end;
d. Insert following code bellow uses clause of implementation

Code: Select all

uses SysUtils, ZMessages;

var
  ServerArgs: array of PChar;
  ServerArgsLen: Integer;

const
  ServerArgsKeyPrefix = 'arg';

procedure BuildServerArguments(Options: TStrings);
var
  Tmp: TStringList;
  i: Integer;

begin
  Tmp := TStringList.Create;
  try
    Tmp.Add(ParamStr(0));
    for i := 0 to Options.Count - 1 do
      if SameText(ServerArgsKeyPrefix, Copy(Options.Names[i], 1, Length(ServerArgsKeyPrefix))) then
        Tmp.Add(Options.ValueFromIndex[i]);
    ServerArgsLen := Tmp.Count;
    SetLength(ServerArgs, ServerArgsLen);
    for i := 0 to ServerArgsLen - 1 do
      ServerArgs[i] := StrNew(PChar(Tmp[i]));
  finally
    Tmp.Free;
  end;
end;
e. Implement procedure BuildOptions(Options: TStrings); in each of driver interface.

Code: Select all

procedure TZMySQL5PlainDriver.BuildArguments(Options: TStrings);
begin
  // leave blank for non embedded
end;

procedure TZMySQLD5PlainDriver.BuildArguments(Options: TStrings);
begin
  BuildServerArguments(Options);
end;
f. Replace Init function for existing embedded driver interface with following code (original line is commented).

Code: Select all

function TZMySQLD5PlainDriver.Init(var Handle: PZMySQLConnect): PZMySQLConnect;
begin
  if @MYSQL_API.mysql_server_init <> nil then
    MYSQL_API.mysql_server_init(ServerArgsLen, ServerArgs, @SERVER_GROUPS);
//    MYSQL_API.mysql_server_init(3, @DEFAULT_PARAMS, @SERVER_GROUPS);
  Handle := MYSQL_API.mysql_init(nil);
  Result := Handle;
end;
2. ZdbcMySql.pas

Insert code commented below to the existing code:

Code: Select all

function TZMySQLDriver.Connect(const Url: string; Info: TStrings): IZConnection;
var
  TempInfo: TStrings;
  HostName, Database, UserName, Password: string;
  Port: Integer;
  PlainDriver: IZMySQLPlainDriver;
begin
  TempInfo := TStringList.Create;
  try
    PlainDriver := GetPlainDriver(Url);
    ResolveDatabaseUrl(Url, Info, HostName, Port, Database,
      UserName, Password, TempInfo);
	// insert this line
    if PlainDriver <> nil then
      PlainDriver.BuildArguments(TempInfo);
    // end of insert line
    Result := TZMySQLConnection.Create(Self, Url, PlainDriver, HostName, Port,
      Database, UserName, Password, TempInfo);
  finally
    TempInfo.Free;
  end;
end;
I have tested it and it work fine. And you can specify as much as server argument to MySQL Embedded server.

Posted: 28.09.2006, 09:26
by mdaems
Wow,

I'm happy somebody really uses embedded. We were waitimg for some confirmation that it effectively works. :thanks:

I'm even more happy somebody wanted to write and test the code to pass arguments to the embedded drivers. Can you make sure the datadir parameter is always defaulted when no (or not all) arguments are passed using your solution?

Can you :!: please :!: send me the changed files? (SVN testing branch patch would be even better, but don't take the effort of installing everything)
I'll integrate this ASAP to the project. (At most some days after I receive it, promised)

Mark

MySQL Embedded modified Library

Posted: 29.09.2006, 07:43
by tohenk
I haven't added for --datadir checking routine. But May be later.

Posted: 29.09.2006, 09:32
by fduenas
Hi Finally some did what i was trying to do time ago, I'm happy to hear about it.

Mark I will try to apply the changes and check if it works ok,
then i will make the patch for latest revision and send it to you.


Thanks tohenk, and do you have any valid Embedded server dll for mysql 5.0?. can you send it to my email plz fduenas@gmail.com ? or upload it here compressed, it can be a usefull contribution

BTW sorry for the long absence but got very sick, now i'm gettin back to the virtual world.

regards

Posted: 30.09.2006, 09:42
by tohenk
I haven't see any MySQL Embedded library bundled since version 5.0.9-beta. So, I have used this old one.

Unfortunately, because of size limitation of an attachment, I can't put it
this forum. I have emailed a copy to fduenas@gmail.com.

Regards!

Posted: 03.10.2006, 02:18
by fduenas
Hi Mark and tohenk

I have applied tohenk's modifications to revision 101.
With 4.1 seems to work ok :D at first

Misteriously i have some problems working with embedded 5.0 at first, but now seems to work ok, very, very strange. :shock:

For Notes to the documnetation, embedded server needs the following folders / files to work (at least for 5.0):
* /data or custom base data directory and the needed databases
* /shared/charsets or custom charset directory where charset files (*.xml) are contained
* /shared/english or custom language folder where the localized errmsg.sys files is contained.

Without this files and folders the server will not be initiated and will throw an AV error when trying to connect.

Maybe also this error can be cached it occurs at line 374 in ZDbcMysql, when it tries to call a libmysqlX.dll function (SetOptions) using the FHandle variable that in this case has a null value.

I have tried to work with embedded library 5.0 that Tohenk send me and seems to work ok

Im' attacthing th changed files for revision 101 including the corresponding patch files (*.diff)

I made some little modifications like Changed the argument name prefix to 'ServerArgument', now this variable is declared as a constant in ZPlainMySQLConstants.pas. Also added the '--datadir' variable checking.

Mark i will send you the changed files and the patches to your email, check if the 'ServerArguments' name prefix for the variable can be ok, if not we can change it to another name.

Regards

Posted: 03.10.2006, 06:12
by fduenas
Also I'm attatching a demo for using embedded server, mabe it can be adapted to be ageneric example for using an embedded server. You need either libmysqld41.dll or libmysqld50.dll to run the demo.

Posted: 03.10.2006, 07:51
by mdaems
Hi Tohenk and Fduenas,

I Just applied this patch to SVN. (Rev102)
I don't know yet when I'll package it for download, but I think it will be soon.

Correction : Package is ready for download now.

Mark

Posted: 09.10.2006, 20:20
by Anton7
I can not install pached zeoslib and zeoslib.Rev102 on bcb6,
[Pascal Error] ZPlainMySqlDriver.pas(961): Undeclared identifier: 'ValueFromIndex' :(

p.s. i have changed a string "TmpList.Add(Options.ValueFromIndex);" to "TmpList.Add(Options.Values[Options.Names]);". Is it correct?

Posted: 09.10.2006, 21:02
by fduenas
Plz hcek there are no old dcu and pas files of previous zeoslib version.

I have downloaded latest revision and all works ok.

Posted: 10.10.2006, 07:51
by mdaems
If it works now, I think it's correct. Probably ValueFromIndex is a new function since Delphi 7? Can anybody confirm this?
@fduenas : Can you check if Anton's version works as well? Maybe we best IFDEF it for versions before Delphi 7. Or we do it always like that (commented so we always know why)?

Mark

Posted: 10.10.2006, 20:14
by mdaems
Should be fixed : see http://zeos.firmos.at/viewtopic.php?t=802
It was a new function indeed.

Mark

Posted: 11.10.2006, 05:13
by fduenas
Hi Mark, ok, I will se it iof should. sorry but haven't time to rtead the forum recently. BTW have you received the corrected delphi10 packages?