unit uADOQuery;

{$I heverdef.inc}

interface

uses ADODB, Rubies;

var
  cADOQuery: Tvalue;

function ap_cADOQuery: Tvalue;
function ap_iADOQuery(real: TADOQuery; owner: Tvalue): Tvalue;
procedure Init_ADOQuery;

implementation

uses
{$IFDEF COMP10_UP}
  WideStrings,
{$ENDIF}
  SysUtils, Classes, uDefUtils, Pythia, uRDBExt,
  uADODataSet, uParameter;

function ap_cADOQuery: Tvalue;
begin
  result := cADOQuery;
end;

procedure ADOQuery_setup(obj: Tvalue; real: TADOQuery);
begin
  DataSet_setup(obj, real);
end;

function ADOQuery_alloc(This: Tvalue; real: TADOQuery): Tvalue;
begin
  result := ChildAlloc(This, real);
  ADOQuery_setup(result, real);
end;

function ap_iADOQuery(real: TADOQuery; owner: Tvalue): Tvalue;
begin
  result := ADOQuery_alloc(cADOQuery, real);
  ap_owner(result, owner);
end;

function ap_iADOQuery_v(var obj; owner: Tvalue): Tvalue;
begin
  result := ap_iADOQuery(TADOQuery(obj), owner);
end;

function ADOQuery_new(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
begin
  real := TADOQuery.Create(nil);
  result := DataSet_alloc(This, real);
  DataSet_setup(result, real);

  rb_obj_call_init(result, argc, argv);
end;

function ADOQuery_execute(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
  p: Pvalue;
begin
  real := ap_data_get_struct(This);

  if argc > 0 then
  begin
    p := argv;
    real.Close;
    real.SQL.Text := dl_String(p^);
  end;
  try
    real.ExecSQL;
  except
    on E: Exception do
      ap_raise(ap_eDatabaseError, E.message);
  end;
  result := Qnil;
end;

function ADOQuery_exec_sql(This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
begin
  result := Qnil;
  real := ap_data_get_struct(This);
  try
    result := ap_Integer(real.ExecSQL);
  except
    on E: Exception do
      ap_raise(ap_eDatabaseError, E.message);
  end;
end;

function ADOQuery_open(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
  p: Pvalue;
begin
  real := ap_data_get_struct(This);
  if argc > 0 then
  begin
    p := argv;
    real.Close;
    real.SQL.Text := dl_String(p^);
  end;
//  try
    real.Open;
//  except
//    on E: Exception do
//      ap_raise(ap_eDatabaseError, E.message);
//  end;
  result := This;
end;

function ADOQuery_get_sql(This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
{$IFDEF COMP10_UP}
  wstrings: TWideStrings;
  i: Integer;
{$ENDIF}
  strings: TStrings;
begin
  real := ap_data_get_struct(This);
{$IFDEF COMP10_UP}
  result := ap_StringList_new;
  strings := dl_Strings(result);
  wstrings := real.SQL;
  for i := 0 to wstrings.Count - 1 do
    strings.Add(wstrings[i]);
{$ELSE}
  strings := real.SQL;
  result := ap_iStrings(strings, This);
{$ENDIF}
end;

function ADOQuery_get_parameters(This: Tvalue): Tvalue; cdecl;
var
  real: TADOQuery;
begin
  real := ap_data_get_struct(This);
  result := ap_iParameters(real.Parameters, This);
end;

procedure Init_ADOQuery;
begin
  cADOQuery := DefinePersistentClass(ap_mRDB, TADOQuery, cADODataSet, ap_iADOQuery_v);
  DefineSingletonMethod(cADOQuery, 'new', ADOQuery_new);
  DefineMethod(cADOQuery, 'execute', ADOQuery_execute);
  rb_define_method(cADOQuery, 'exec_sql', @ADOQuery_exec_sql, 0);
//  rb_define_method(cADOQuery, 'open', @ADOQuery_open, -1);
  DefineAttrGet(cADOQuery, 'sql', ADOQuery_get_sql);
  DefineAttrGet(cADOQuery, 'parameters', ADOQuery_get_parameters);
end;

end.
