unit uSQLQuery;

interface

uses Rubies, SqlExpr;

var
  cSQLQuery: Tvalue;

function ap_cSQLQuery: Tvalue;
function ap_iSQLQuery(real: TSQLQuery; owner: Tvalue): Tvalue;
procedure Init_SQLQuery;

implementation

uses SysUtils, uDefUtils, Pythia, uRDBExt{, uDataSet, uParam};

function ap_cSQLQuery: Tvalue;
begin
  result := cSQLQuery;
end;

procedure SQLQuery_setup(obj: Tvalue; real: TSQLQuery);
begin
  DataSet_setup(obj, real);
end;

function SQLQuery_alloc(This: Tvalue; real: TSQLQuery): Tvalue;
begin
  result := ChildAlloc(This, real);
  SQLQuery_setup(result, real);
end;

function ap_iSQLQuery(real: TSQLQuery; owner: Tvalue): Tvalue;
begin
  result := SQLQuery_alloc(cSQLQuery, real);
  ap_owner(result, owner);
end;

function ap_iSQLQuery_v(var obj; owner: Tvalue): Tvalue;
begin
  result := ap_iSQLQuery(TSQLQuery(obj), owner);
end;

function SQLQuery_new(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
  conn: TSQLConnection;
  v:Tvalue;
  args: array of Tvalue;
begin
  real := TSQLQuery.Create(nil);
  result := DataSet_alloc(This, real);
  DataSet_setup(result, real);
  if argc > 0 then begin
    SetLength(args, argc);
    args := argv;
    try
      if args[0] <> Qnil then begin
        v := args[0];
        rb_iv_set(result, '@sql_connection', v);
        ap_data_get_object(v, TSQLConnection, conn);
        real.SQLConnection := conn;
      end;
      if argc > 1 then begin
        real.SQL.Text := dl_String(args[1]);
      end;
    except
      on E: Exception do
        ap_raise(ap_eDatabaseError, E.message);
    end;
  end;
  rb_obj_call_init(result, argc, argv);
end;

function SQLQuery_execute(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
  args: array of Tvalue;
begin
  real := ap_data_get_struct(This);

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

function SQLQuery_exec_sql(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
  args: array of Tvalue;
  ExecDirect : boolean;
begin
  result := Qnil;
  real := ap_data_get_struct(This);
  ExecDirect := False; // default
  if argc > 0 then
  begin
    SetLength(args, argc);
    args := argv;
    ExecDirect := dl_Boolean(args[0]);
  end;
  try
    result := ap_Integer(real.ExecSQL(ExecDirect));
  except
    on E: Exception do
      ap_raise(ap_eDatabaseError, E.message);
  end;
end;

function SQLQuery_open(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
  args: array of Tvalue;
begin
  real := ap_data_get_struct(This);
  if argc > 0 then
  begin
    SetLength(args, argc);
    args := argv;
    real.Close;
    real.SQL.Text := dl_String(args[0]);
  end;
//  try
    real.Open;
//  except
//    on E: Exception do
//      ap_raise(ap_eDatabaseError, E.message);
//  end;
  result := This;
end;

function SQLQuery_get_sql(This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
begin
  real := ap_data_get_struct(This);
  result := ap_iStrings(real.SQL, This);
end;

function SQLQuery_get_params(This: Tvalue): Tvalue; cdecl;
var
  real: TSQLQuery;
begin
  real := ap_data_get_struct(This);
  result := ap_iParams(real.Params, This);
end;

procedure Init_SQLQuery;
begin
  cSQLQuery := DefinePersistentClass(ap_mRDB, TSQLQuery, ap_cDataSet, nil);
  DefineSingletonMethod(cSQLQuery, 'new', SQLQuery_new);
  DefineMethod(cSQLQuery, 'execute', SQLQuery_execute);
  rb_define_method(cSQLQuery, 'exec_sql', @SQLQuery_exec_sql, -1);
//  rb_define_method(cSQLQuery, 'open', @SQLQuery_open, -1);
  DefineAttrGet(cSQLQuery, 'sql', SQLQuery_get_sql);
  DefineAttrGet(cSQLQuery, 'params', SQLQuery_get_params);
end;

end.
