unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActiveX, StdCtrls, Menus, NiApiLib_TLB, ComCtrls, FileCtrl ;

//******************************************************************************
//  TNISession
//******************************************************************************
  type TNISession = class
  private

  public
    S : TSrvrSession ;

    // Constructor/destructor
    constructor Create ;
    destructor  Destroy ; override ;

    // TSrvrSession methods
    procedure Connect( szHostAddr : String ; iPort : Integer; szLogin : String ; szPassword : String ; szCatalog : String ) ;
    procedure Disconnect ;

    // TSrvrSession events
    procedure OnLogin( ASender : TObject ; LoginResult : Integer ) ;
    procedure OnConnectionLost( ASender : TObject ) ;
//    procedure OnMessage( ASender : TObject ; const msg : IDispatch ) ;

  end;

//******************************************************************************
// TNITable
//******************************************************************************
type TNITable = class
private

public
    __Table : TTable ;

    // Constructor/destructor
    constructor Create ;
    destructor Destroy ; override ;

    // TTable methods
    procedure Open( const SrvrSession : IDispatch ; const szName: WideString ; Type_: ETableType ) ; safecall ;
    //function GetData( Filter : OleVariant ) : Integer ; safecall ;
    function getdata : integer; safecall;
    function GetSlice( Filter : OleVariant ) : Integer ; safecall ;
    procedure SetOnlineUpdates( Val : ESubscribtion ) ; safecall ;
    procedure Insert(const NiDataRow: IDispatch); safecall;
    procedure Modify(const NiDataRow: IDispatch); safecall;
    //procedure Modify(const NiDataRow: IDispatch); safecall;
    function AddUpdateFilter(ParentId: Integer; Operation: ELogicalOperation;
                              var Field: OleVariant; Condition: ECondition; var Value: OleVariant): Integer; safecall;
    // TTable events
    procedure OnData( ASender : TObject ; iCode : Integer ; const DataRowSet : IDispatch ; const szTableName : WideString ) ;
    procedure OnDataComplete( ASender : TObject ; iCode : Integer ; const szTableName : WideString ) ;
    procedure OnInsert( ASender : TObject ; const NiDataRow : IDispatch ; const szTableName : WideString ) ;
    procedure OnModify( ASender : TObject ; const NiDataRow : IDispatch ; const szTableName : WideString ) ;
    procedure OnDelete( ASender : TObject ; iRecid : Integer ; const szTableName : WideString ) ;
end ;

//Objects described

type
  TForm1 = class(TForm)
    Connect: TButton;
    Label8: TLabel;
    Label9: TLabel;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ConnectClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;



procedure encode_base64_block(in_block : PChar;in_size : DWORD;out_block : PChar);stdcall;external 'BASE64.DLL' name 'encode_base64_block';
function decode_base64_block(in_block : PChar;in_size : DWORD; out_block : PChar) : DWORD;stdcall;external 'BASE64.DLL' name 'decode_base64_block';


var
  Form1: TForm1;
  //OBJECTS
  NISession : TNISession ;
  tblFilesInfo : TNITable ;
  tblFiles: TNITable;
  //Session parameters
  addr:string;
  port: integer;
  login:string;
  pass:string;
  catalog:string;
  //files
  filename:string;
  infile:Tfilestream;
  logfile:Tfilestream;
  coded:Tfilestream;
  outfile:Tfilestream;
  insert_size: integer;
  fdate: string;
  ftime: string;
  //arrays
  P1:array[0..250] of char;
  p2:array[0..250] of char;
  p3:array[0..80] of char;
  //different blocks
  fiels_size:integer;
  block_size:integer;
  new_size:integer;
  //additional
  codefrom:integer;
  codeto:integer;
  main_recid:integer;
implementation

{$R *.dfm}

//******************************************************************************
// constructor TNISession.Create
//******************************************************************************
constructor TNISession.Create ;
begin
  S         := TSrvrSession.Create( nil ) ;
  S.OnLogin := self.OnLogin ;
  S.OnConnectionLost := self.OnConnectionLost ;
//  S.OnMessage := self.OnMessage ;
end ;

//******************************************************************************
// destructor TNISession.Destroy
//******************************************************************************
destructor TNISession.Destroy ;
begin
  FreeAndNil( S ) ;
end ;

//**********************************************
//CONNECT METHOD
//**********************************************
procedure TNISession.Connect( szHostAddr : String ;
                              iPort : Integer ;
                              szLogin : String ;
                              szPassword : String ;
                              szCatalog : String ) ;
begin
      S.HostAddr := szHostAddr ;
      S.HostPort := iPort ;
      S.Name     := szLogin ;
      S.Password := szPassword ;
      if szCatalog <> '' then
          S.CatalogName := szCatalog ;
      S.Connect1 ;
end;

//***************************************************
//DISCONNECT METHOD
//***************************************************
procedure TNISession.Disconnect ;
begin
  S.Disconnect1 ;
end ;

//*************************************************
//ONLOGIN EVENT
//*************************************************
procedure TNISession.OnLogin( ASender : TObject ; LoginResult : Integer ) ;
var
 Row : TDataRow ;
 ovItem: OleVariant;
 ovItem1 : Olevariant;
 ovItem2 : OleVariant;
begin
    MessageBox( Form1.Handle, 'Соединение установлено', '', MB_OK or MB_ICONINFORMATION ) ;
    Form1.Label9.Color:=ClLime;
    if (loginresult=0) then
      begin
        //creating insert row
        row:=Tdatarow.Create(nil);
        //parameters
        //------------------------
        filename:='Init.pdf';
        //------------------------
        codeto:=1364;
        codefrom:=82;
        //opening table file_info
        tblfilesinfo.Open(nisession.s.DefaultInterface,'FILES_INFO',0 );
        tblfilesinfo.SetOnlineUpdates(subEnabled );
        //setting update filters
        ovItem1:='I_CLIENT_NAME';
        ovItem2:=codefrom;
        tblfilesinfo.AddUpdateFilter(0,logOr,ovItem1,conEqual,ovItem2);
        ovItem1:='I_FULLNAME';
        ovItem2:=filename;
        tblfilesinfo.AddUpdateFilter(0,logOr,ovItem1,conEqual,ovItem2);
        row.Structure :=tblfilesinfo.__Table.Structure ;
        Form1.label9.caption:='connected';
        //filling insert row
        infile:=tfilestream.Create(filename,fmOpenRead);
        insert_size:=infile.Size;
        DateTimeTostring (ftime, 'hh:nn:ss', fileDateToDateTime (fileGetDate ( inFile.handle ) ));
        DateTimeTostring (fdate, 'dd.mm.yyyy', fileDateToDateTime (fileGetDate ( inFile.handle ) ));
        ovItem:='I_CLIENT_NAME'; Row.Item[ovItem]:=codefrom;
        ovItem:='I_CODE_FROM'; Row.Item[ovItem]:=codeto;
        ovItem:='I_FULLNAME'; Row.Item[ovItem]:=filename;
        ovItem:='I_QUANTITY'; Row.Item[ovItem]:=insert_size;
        ovItem:='I_TIME'; Row.Item[ovItem]:=ftime;
        ovItem:='I_DATE'; Row.Item[ovItem]:=fdate;
        tblFilesInfo.Insert(Row.DefaultInterface );
       // tblfilesinfo.modify (row.DefaultInterface );
      end;

end ;

//************************************************
//OnConnectionLostEvent
//************************************************
procedure TNISession.OnConnectionLost( ASender : TObject ) ;
begin
  MessageBox( 0, 'Соединение потеряно', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
  //MessageBox( Form1.Handle, 'Соединение потеряно', '', MB_OK or MB_ICONINFORMATION ) ;
  Form1.label9.Color:=ClREd;
  Form1.Label9.Caption :='not connected';
end ;

//***************************************
//Session described
//***************************************

//***************************************
//Table description
//***************************************

//***************************************
//CONSTRUCTOR
//***************************************
constructor TNITable.Create ;
begin
    __Table := TTable.Create( nil ) ;
    __Table.OnInsert := self.OnInsert ;
    __Table.OnModify := self.OnModify ;
    __Table.OnDelete := self.OnDelete ;
    __Table.OnData   := self.OnData ;
    __Table.OnDataComplete := self.OnDataComplete ;
end ;

//**************************************
//DESTRUCTOR
//**************************************
destructor TNITable.Destroy ;
begin
  FreeAndNil( __Table ) ;
end ;

//***********************************
//OPEN METHOD
//***********************************
procedure TNITable.Open( const SrvrSession : IDispatch ; const szName: WideString ; Type_: ETableType ) ; safecall ;
begin
  __Table.Open( SrvrSession, szName, Type_ ) ;
end ;

//***********************************
//INSERT METHOD
//***********************************
procedure TNITable.Insert(const NiDataRow: IDispatch); safecall;
begin
    __Table.insert(NiDataRow);
end;

//***********************************
//MODIFY METHOD
//***********************************
procedure TNITable.Modify(const NiDataRow: IDispatch); safecall;
begin
    __Table.Modify (NiDataRow);
end;


//*****************************************************************
//ADDUPDATEFILTER METHOD
//*****************************************************************
function  TNITable.AddUpdateFilter (ParentId: Integer; Operation: ELogicalOperation;
                              var Field: OleVariant; Condition: ECondition; var Value: OleVariant): Integer; safecall;
begin
   addupdatefilter:=__Table.AddUpdateFilter(parentId,Operation,field,condition,value);
end;

//**********************************
//OnDATA EVENT
//**********************************
procedure TNITable.OnData( ASender : TObject ; iCode : Integer ; const DataRowSet : IDispatch ; const szTableName : WideString ) ;
var
  str : string;
  NiDatarowset : Idatarowset;
  Row : IDataRow ;
  ovItem,ovItem1,ovItem2,ovItem3,ovItem4 : OleVariant ;
  j,k:integer;
  count1 : integer;
  count2 : integer;
  //F2: textfile;
begin
end ;

//****************************************
//OnDataComplete EVENT
//****************************************
procedure TNITable.OnDataComplete( ASender : TObject ; iCode : Integer ; const szTableName : WideString ) ;
begin
end ;


//****************************************
//OnInsert EVENT
//****************************************
procedure TNITable.OnInsert( ASender: TObject ; const NiDataRow : IDispatch ; const szTableName : WideString ) ;
var
    Row    : IDataRow ;
    FileRow : Tdatarow;
    rowmy : Tdatarow;
    irowmy:Idatarow;
    ovItem : OleVariant ;
    ovItem1 : OleVariant ;
    ovItem2 : OleVariant ;
    ovItem3 : OleVariant ;
    ovItem4 : OleVariant ;
    ovItem5 : OleVariant ;
    times:integer;
    ost:integer;
    i,j,k:integer; //counter
    fields: integer;
    recnum: integer;  //record number in table FILES
    str:string;
begin
    //MessageBox( 0, 'OnInsert!!', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
    if (sztablename='FILES_INFO') then
      begin
        Row := NiDataRow as IDataRow ;
        FileRow:=tdatarow.Create(nil);
        ovItem:='I_RID';
        main_recid:=row.Item[ovItem];
        //Form1.Canvas.TextOut(10,10,inttostr(main_recid));
        //MessageBox( 0, 'OnInsert!!!', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
        //begin filling the second table
        logfile:=tfilestream.Create('logfile',fmCreate);
        tblfiles.Open(nisession.s.DefaultInterface,'FILES',0);
        filerow.Structure :=tblfiles.__Table.Structure;
        block_size:=3;
        times:=(infile.Size-infile.Position) div block_size;
        ost:=(infile.Size-infile.Position) mod block_size;
        i:=1;
        j:=1;
        recnum:=1;
        fields:=1;
        p3:='';
        while (i<=times+1) do
           begin
              if (i=times+1) then
                begin
                  //MessageBox( 0, 'End!!!', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
                  if (ost>0) then
                    begin
                      infile.Read(p1,ost);
                    end
                  else
                    begin
                      logfile.Write('break',5);
                      break;
                      logfile.Write('break2',6);
                    end;
                end
              else
                begin
                  infile.Read(p1,block_size);
                end;
              //logfile('break',5);
              //MessageBox( 0, 'Step1!!!', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
              //infile.Read(p1,block_size);
              //getting field
              if (fields=1) then
                begin
                  ovItem:='I_TEXT';
                end
              else
                begin
                  ovItem:='I_TEXT'+inttostr(fields);
                end;
              //encoding and creating buffer
              encode_base64_block(p1,block_size,p2);
              k:=1;
              while (k<=4) do
                begin
                  p3[(j-1)*4+(k-1)]:=p2[k-1];
                  k:=k+1;
                end;
              //p3:=p3+p2;
              //dealing with indexes
              if (j=20) then
                begin
                  //last block added to the current field
                  j:=1;
                  if (fields=5) then
                     begin
                       //current field is last field in the current record
                       str:=p3;
                       filerow.Item[ovItem]:=str;
                       //insert
                       ovitem:='I_CLIENT_NAME';filerow.Item [ovItem]:=codeto;
                       ovitem:='I_FILE';filerow.Item [ovItem]:=main_recid;
                       ovitem:='I_BLOCK_NUMBER';filerow.Item [ovItem]:=recnum;
                       tblfiles.Insert(filerow.DefaultInterface );
                       ovitem:='I_TEXT';filerow.Item[ovItem]:='';
                       ovitem:='I_TEXT2';filerow.Item[ovItem]:='';
                       ovitem:='I_TEXT3';filerow.Item[ovItem]:='';
                       ovitem:='I_TEXT4';filerow.Item[ovItem]:='';
                       ovitem:='I_TEXT5';filerow.Item[ovItem]:='';
                       p3:='';
                       fields:=1;
                       recnum:=recnum+1;
                     end
                  else
                     begin
                       //Current field is from 1 to 4
                       str:=p3;
                       filerow.item[ovitem]:=str;
                       p3:='';
                       fields:=fields+1;
                     end;
                end
              else
                begin
                   //current block is among 1..19
                   j:=j+1;
                end;
              logfile.Write(p1,block_size);
              i:=i+1;
           end;

        if ((j=1) and (fields=1)) then
          begin
          //цикл как раз закончился отправкой последней записи (как раз был insert)
          //Поэтому ничего делать не надо
          end
        else
          begin
            //Так как цикл закончился и текущая запись не закончена до конца,
            //то нужно ее записать в базу
            k:=fields;
            if (k=1) then
              begin
                ovitem:='I_TEXT';
              end
            else
              begin
                ovitem:='I_TEXT'+inttostr(k);
              end;
            //записываем текущую строку в соответствующее поле
            str:=p3;
            filerow.Item[ovitem]:=str;
            k:=k+1;
            //оставшиеся поля делаем пустыми
            while (k<=5) do
              begin
                ovitem:='I_TEXT'+inttostr(k);
                filerow.Item[ovitem]:='';
                k:=k+1;
              end;
            ovitem:='I_CLIENT_NAME';filerow.Item [ovItem]:=codeto;
            ovitem:='I_FILE';filerow.Item [ovItem]:=main_recid;
            ovitem:='I_BLOCK_NUMBER';filerow.Item [ovItem]:=recnum;
            tblfiles.Insert(filerow.DefaultInterface );
          end;
        MessageBox( 0, 'File information inserted', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
        
        //----------------------------------
        //Меняем флаг на 0, сигнал к рассылке
        rowmy:=tdatarow.Create(nil);
        rowmy.Structure := tblfilesinfo.__Table.Structure;
        ovitem:='I_RID'; rowmy.Item[ovitem]:=main_recid;
        ovItem:='I_FLAG'; rowmy.Item[ovItem]:='0';
        tblFilesInfo.Modify (rowmy.DefaultInterface );
      end
    else

      begin

      end;

end ;

//****************************************
//OnModify EVENT
//****************************************
procedure TNITable.OnModify( ASender : TObject ; const NiDataRow : IDispatch ; const szTableName : WideString ) ;
begin
  MessageBox( 0, 'OnModify!!!', 'NiApi.dll test', MB_OK or MB_ICONEXCLAMATION ) ;
end ;

//****************************************
//OnDelete EVENT
//****************************************
procedure TNITable.OnDelete( ASender : TObject ; iRecid : Integer ; const szTableName : WideString ) ;
begin
end ;

//****************************************
//GetData Method
//****************************************
function TNITable.GetData : Integer ; safecall ;
begin
    GetData := __Table.GetData(  ) ;
end ;

//function TNITable.GetData( Filter : OleVariant ) : Integer ; safecall ;
//begin
//    GetData := __Table.GetData( Filter ) ;
//end ;

//****************************************
//GetSlice Method
//****************************************
function TNITable.GetSlice( Filter : OleVariant ) : Integer ; safecall ;
begin
    GetSlice := __Table.GetSlice( Filter ) ;
end ;

//****************************************
//Setonlineupdatesmethod
//****************************************
procedure TNItable.SetOnlineUpdates( Val : ESubscribtion ) ; safecall ;
begin
    __Table.SetOnlineUpdates( Val ) ;
end ;

//***********************
//NiTable described
//***********************

procedure TForm1.FormCreate(Sender: TObject);
begin
    // OLE initialization
    CoInitializeEx ( nil, coinit_multithreaded ) ;

    // Create main SrvrSession :
    NISession := TNISession.Create ;
    tblFilesInfo := TNITable.Create ;
    tblFiles := TNITable.create;
end;

procedure TForm1.ConnectClick(Sender: TObject);
begin
    addr:='10.200.200.201';
    port:=2900 ;
    login:='nik2';
    pass:='nik2';
    catalog:='D:\Catalog.xml' ;
    NISession.Connect( addr, port, login, pass, catalog ) ;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  NISession.disconnect;
end;

end.
