unit uQuery;

interface

uses DBTables, Rubies;

var
  cQuery: Tvalue;

function ap_cQuery: Tvalue;
function ap_iQuery(real: TQuery; owner: Tvalue): Tvalue;
procedure Init_Query;

implementation

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

function ap_cQuery: Tvalue;
begin
  result := cQuery;
end;

procedure Query_setup(obj: Tvalue; real: TQuery);
begin
  DataSet_setup(obj, real);
end;

function Query_alloc(This: Tvalue; real: TQuery): Tvalue;
begin
  result := ChildAlloc(This, real);
  Query_setup(result, real);
end;

function ap_iQuery(real: TQuery; owner: Tvalue): Tvalue;
begin
  result := Query_alloc(cQuery, real);
  ap_owner(result, owner);
end;

function ap_iQuery_v(var obj; owner: Tvalue): Tvalue;
begin
  result := ap_iQuery(TQuery(obj), owner)
end;

function Query_new(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TQuery;
  args: array of Tvalue;
  Database: TDatabase;
  v: Tvalue;
begin
  real := TQuery.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];
        case RTYPE(v) of
        T_STRING:
          real.DatabaseName := dl_String(v);
        else
          ap_data_get_object(v, TDatabase, Database);
          rb_iv_set(result, '@database', v);
          real.DatabaseName := Database.DatabaseName;
          real. SessionName := Database. SessionName;
        end;
      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;

  ap_obj_call_init(result, argc, argv);
end;

function Query_execute(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TQuery;
  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 := This;
end;

function Query_open(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
var
  real: TQuery;
  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 Query_get_sql(This: Tvalue): Tvalue; cdecl;
var
  real: TQuery;
begin
  real := ap_data_get_struct(This);
  result := ap_iStrings(real.SQL, This);
end;

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

procedure Init_Query;
begin
  cQuery := DefinePersistentClass(ap_mRDB, TQuery, ap_cDataSet, ap_iQuery_v);
  DefineSingletonMethod(cQuery, 'new', Query_new);
  DefineMethod(cQuery, 'execute', Query_execute);
//[ap-dev:0814]
//rb_define_method(cQuery, 'open', @Query_open, -1);
  DefineAttrGet(cQuery, 'sql', Query_get_sql);
  DefineAttrGet(cQuery, 'params', Query_get_params);
end;

end.
