Ignore:
Timestamp:
Mar 26, 2018, 11:37:46 PM (6 years ago)
Author:
chronos
Message:
  • Modified: Improved handling of SQL commands by XML backend.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DbEngines/UEngineXML.pas

    r23 r24  
    3333    function CheckNext(var Source: string; Text: string): Boolean;
    3434    function GetNextPart(var Text: string; Separator: string = ' '): string;
     35    procedure QuerySelect(Text: string; DbRows: TDbRows = nil);
     36    procedure QueryInsert(Text: string; DbRows: TDbRows = nil);
     37    procedure QueryDelete(Text: string; DbRows: TDbRows = nil);
     38    procedure QueryUpdate(Text: string; DbRows: TDbRows = nil);
    3539    function TableCreateIfNotExists(Name: string): TTable;
    3640    function FieldCreateIfNotExists(TableName, FieldName: string; DataType: TDataType): TField;
     
    6468  SWrongFileFormat = 'Wrong file format';
    6569  STableNotFound = 'Table %s not found';
     70  SFieldNotFound = 'Table field %s not found';
    6671  SUnsupportedSqlCommand = 'Unsupported SQL command: %s';
    6772  SColumnNotFoundInTable = 'Column %s not found in table %s';
     
    363368end;
    364369
    365 procedure TDatabaseXML.Query(Text: string; DbRows: TDbRows = nil);
     370procedure TDatabaseXML.QuerySelect(Text: string; DbRows: TDbRows = nil);
    366371var
    367372  Command: string;
     
    372377  I: Integer;
    373378  F: Integer;
    374   Row: TRecord;
    375379  WhereName: string;
    376380  WhereValue: string;
    377   InsertValues: TStringList;
    378   Field: TField;
    379   FieldIndex: Integer;
    380   NewValue: TValue;
    381   ValueIndex: Integer;
    382 begin
    383   Command := GetNextPart(Text);
    384   if Command = 'SELECT' then begin
    385     DbRows.Count := 0;
    386     Columns := GetNextPart(Text);
    387     Expect(Text, 'FROM');
    388     TableName := GetNextPart(Text);
    389     if CheckNext(Text, 'WHERE') then begin
    390       WhereName := GetNextPart(Text);
    391       Command := GetNextPart(Text);
    392       if Command = '=' then begin
    393         WhereValue := GetNextPart(Text);
    394       end else raise Exception.Create('Expression error');
    395     end;
    396     if TableName = 'Model' then begin
     381begin
     382  DbRows.Count := 0;
     383  Columns := GetNextPart(Text);
     384  Expect(Text, 'FROM');
     385  TableName := GetNextPart(Text);
     386  if CheckNext(Text, 'WHERE') then begin
     387    WhereName := GetNextPart(Text);
     388    Command := GetNextPart(Text);
     389    if Command = '=' then begin
     390      WhereValue := GetNextPart(Text);
     391    end else raise Exception.Create('Expression error');
     392  end;
     393  if TableName = 'Model' then begin
     394    if Columns = '*' then begin
     395      for I := 0 to Tables.Count - 1 do begin
     396        NewRecord := TDictionaryStringString.Create;
     397        NewRecord.Add('Name', TTable(Tables[I]).Name);
     398        NewRecord.Add('Caption', TTable(Tables[I]).Caption);
     399        DbRows.Add(NewRecord);
     400      end;
     401    end else
     402    if Columns = 'COUNT(*)' then begin
     403      NewRecord := TDictionaryStringString.Create;
     404      NewRecord.Add('COUNT(*)', IntToStr(Tables.Count));
     405      DbRows.Add(NewRecord);
     406    end else raise Exception.Create('Unsupported columns ' + Columns + ' specification');
     407  end else
     408  if TableName = 'ModelField' then begin
     409    if WhereName = 'Model' then
     410      Table := Tables.SearchByName(WhereValue)
     411      else Table := nil;
     412    if Assigned(Table) then begin
    397413      if Columns = '*' then begin
    398         for I := 0 to Tables.Count - 1 do begin
     414        for I := 0 to Table.Fields.Count - 1 do begin
    399415          NewRecord := TDictionaryStringString.Create;
    400           NewRecord.Add('Name', TTable(Tables[I]).Name);
    401           NewRecord.Add('Caption', TTable(Tables[I]).Caption);
     416          NewRecord.Add('Name', TField(Table.Fields[I]).Name);
     417          NewRecord.Add('Caption', TField(Table.Fields[I]).TextBefore);
     418          NewRecord.Add('Model', Table.Name);
     419          NewRecord.Add('DataType', TField(Table.Fields[I]).DataType.Name);
    402420          DbRows.Add(NewRecord);
    403421        end;
     
    405423      if Columns = 'COUNT(*)' then begin
    406424        NewRecord := TDictionaryStringString.Create;
    407         NewRecord.Add('COUNT(*)', IntToStr(Tables.Count));
     425        NewRecord.Add('COUNT(*)', IntToStr(Table.Fields.Count));
    408426        DbRows.Add(NewRecord);
    409427      end else raise Exception.Create('Unsupported columns ' + Columns + ' specification');
    410     end else
    411     if TableName = 'ModelField' then begin
    412       if WhereName = 'Model' then
    413         Table := Tables.SearchByName(WhereValue)
    414         else Table := nil;
    415       if Assigned(Table) then begin
    416         if Columns = '*' then begin
    417           for I := 0 to Table.Fields.Count - 1 do begin
    418             NewRecord := TDictionaryStringString.Create;
    419             NewRecord.Add('Name', TField(Table.Fields[I]).Name);
    420             NewRecord.Add('Caption', TField(Table.Fields[I]).TextBefore);
    421             NewRecord.Add('Model', Table.Name);
    422             NewRecord.Add('DataType', TField(Table.Fields[I]).DataType.Name);
    423             DbRows.Add(NewRecord);
    424           end;
    425         end else
    426         if Columns = 'COUNT(*)' then begin
     428    end else raise Exception.Create(Format(STableNotFound, [WhereValue]));
     429  end else begin
     430    Table := Tables.SearchByName(TableName);
     431    if Assigned(Table) then begin
     432      if Columns = '*' then begin
     433        for I := 0 to Table.Records.Count - 1 do begin
    427434          NewRecord := TDictionaryStringString.Create;
    428           NewRecord.Add('COUNT(*)', IntToStr(Table.Fields.Count));
     435          for F := 0 to Table.Fields.Count - 1 do
     436            NewRecord.Add(TField(Table.Fields[F]).Name, TValue(TRecord(Table.Records[I]).Values[I]).GetString);
    429437          DbRows.Add(NewRecord);
    430         end else raise Exception.Create('Unsupported columns ' + Columns + ' specification');
    431       end else raise Exception.Create(Format(STableNotFound, [WhereValue]));
    432     end else begin
    433       Table := Tables.SearchByName(TableName);
    434       if Assigned(Table) then begin
    435         if Columns = '*' then begin
    436           for I := 0 to Table.Records.Count - 1 do begin
    437             NewRecord := TDictionaryStringString.Create;
    438             for F := 0 to Table.Fields.Count - 1 do
    439               NewRecord.Add(TField(Table.Fields[F]).Name, TValue(TRecord(Table.Records[I]).Values[I]).GetString);
    440             DbRows.Add(NewRecord);
    441           end;
    442         end else
    443         if Columns = 'COUNT(*)' then begin
    444           NewRecord := TDictionaryStringString.Create;
    445           NewRecord.Add('COUNT(*)', IntToStr(Table.Records.Count));
    446           DbRows.Add(NewRecord);
    447         end else raise Exception.Create('Unsupported columns ' + Columns + ' specification');
    448       end else raise Exception.Create(Format(STableNotFound, [TableName]));
    449     end;
    450   end else
    451   if Command = 'INSERT' then begin
    452     InsertValues := TStringList.Create;
    453     Expect(Text, 'INTO');
    454     TableName := GetNextPart(Text);
    455     Expect(Text, '(');
     438        end;
     439      end else
     440      if Columns = 'COUNT(*)' then begin
     441        NewRecord := TDictionaryStringString.Create;
     442        NewRecord.Add('COUNT(*)', IntToStr(Table.Records.Count));
     443        DbRows.Add(NewRecord);
     444      end else raise Exception.Create('Unsupported columns ' + Columns + ' specification');
     445    end else raise Exception.Create(Format(STableNotFound, [TableName]));
     446  end;
     447end;
     448
     449procedure TDatabaseXML.QueryInsert(Text: string; DbRows: TDbRows);
     450var
     451  TableName: string;
     452  Table: TTable;
     453  Row: TRecord;
     454  InsertValues: TStringList;
     455  Field: TField;
     456  FieldIndex: Integer;
     457  ValueIndex: Integer;
     458begin
     459  InsertValues := TStringList.Create;
     460  Expect(Text, 'INTO');
     461  TableName := GetNextPart(Text);
     462  Expect(Text, '(');
     463  InsertValues.Add(GetNextPart(Text) + InsertValues.NameValueSeparator);
     464  while CheckNext(Text, ',') do begin
    456465    InsertValues.Add(GetNextPart(Text) + InsertValues.NameValueSeparator);
    457     while CheckNext(Text, ',') do begin
    458       InsertValues.Add(GetNextPart(Text) + InsertValues.NameValueSeparator);
    459     end;
    460     Expect(Text, ')');
    461     Expect(Text, 'VALUES');
    462     Expect(Text, '(');
    463     ValueIndex := 0;
     466  end;
     467  Expect(Text, ')');
     468  Expect(Text, 'VALUES');
     469  Expect(Text, '(');
     470  ValueIndex := 0;
     471  InsertValues.ValueFromIndex[ValueIndex] := GetNextPart(Text);
     472  Inc(ValueIndex);
     473  while CheckNext(Text, ',') do begin
    464474    InsertValues.ValueFromIndex[ValueIndex] := GetNextPart(Text);
    465475    Inc(ValueIndex);
     476  end;
     477  Expect(Text, ')');
     478  if TableName = 'Model' then begin
     479    Table := Tables.AddNew(InsertValues.Values['Name']);
     480    Table.Caption := InsertValues.Values['Caption'];
     481  end else
     482  if TableName = 'ModelField' then begin
     483    Table := Tables.SearchByName(InsertValues.Values['Model']);
     484    if Assigned(Table) then begin
     485      Field := Table.Fields.AddNew(InsertValues.Values['Name'], DbManager.DataTypes.SearchByType(ftString));
     486      Field.TextBefore := InsertValues.Values['Caption'];
     487      Field.DataType := DbManager.DataTypes.SearchByName(InsertValues.Values['DataType']);
     488    end else raise Exception.Create(Format(STableNotFound, [InsertValues.Values['Model']]));
     489  end else begin
     490    Table := Tables.SearchByName(TableName);
     491    if Assigned(Table) then begin
     492      Row := Table.Records.AddNew;
     493      for ValueIndex := 0 to InsertValues.Count - 1 do begin
     494        Field := Table.Fields.SearchByName(InsertValues.Names[ValueIndex]);
     495        if Assigned(Field) then begin
     496          FieldIndex := Table.Fields.IndexOf(Field);
     497          TValue(Row.Values[FieldIndex]).SetString(InsertValues.ValueFromIndex[ValueIndex]);
     498        end else raise Exception.Create(Format(SColumnNotFoundInTable,
     499          [InsertValues.Names[ValueIndex], TableName]));
     500      end;
     501    end else raise Exception.Create(Format(STableNotFound, [TableName]));
     502  end;
     503  InsertValues.Free;
     504end;
     505
     506procedure TDatabaseXML.QueryDelete(Text: string; DbRows: TDbRows);
     507var
     508  TableName: string;
     509  Table: TTable;
     510  Row: TRecord;
     511  Field: TField;
     512  WhereValues: TStringList;
     513  ValueName: string;
     514begin
     515  Expect(Text, 'FROM');
     516  TableName := GetNextPart(Text);
     517
     518  if CheckNext(Text, 'WHERE') then begin
     519    WhereValues := TStringList.Create;
     520    ValueName := GetNextPart(Text);
     521    Expect(Text, '=');
     522    WhereValues.Add(ValueName + WhereValues.NameValueSeparator + GetNextPart(Text));
    466523    while CheckNext(Text, ',') do begin
    467       InsertValues.ValueFromIndex[ValueIndex] := GetNextPart(Text);
    468       Inc(ValueIndex);
     524      ValueName := GetNextPart(Text);
     525      Expect(Text, '=');
     526      WhereValues.Add(ValueName + WhereValues.NameValueSeparator + GetNextPart(Text));
    469527    end;
    470     Expect(Text, ')');
    471     if TableName = 'Model' then begin
    472       Table := Tables.AddNew(InsertValues.Values['Name']);
    473       Table.Caption := InsertValues.Values['Caption'];
    474     end else
    475     if TableName = 'ModelField' then begin
    476       Table := Tables.SearchByName(InsertValues.Values['Model']);
    477       if Assigned(Table) then begin
    478         Field := Table.Fields.AddNew(InsertValues.Values['Name'], DbManager.DataTypes.SearchByType(ftString));
    479         Field.TextBefore := InsertValues.Values['Caption'];
    480         Field.DataType := DbManager.DataTypes.SearchByName(InsertValues.Values['DataType']);
    481       end else raise Exception.Create(Format(STableNotFound, [InsertValues.Values['Model']]));
    482     end else begin
    483       Table := Tables.SearchByName(TableName);
    484       if Assigned(Table) then begin
    485         Row := Table.Records.AddNew;
    486         for ValueIndex := 0 to InsertValues.Count - 1 do begin
    487           Field := Table.Fields.SearchByName(InsertValues.Names[ValueIndex]);
    488           if Assigned(Field) then begin
    489             FieldIndex := Table.Fields.IndexOf(Field);
    490             TValue(Row.Values[FieldIndex]).SetString(InsertValues.ValueFromIndex[ValueIndex]);
    491           end else raise Exception.Create(Format(SColumnNotFoundInTable,
    492             [InsertValues.Names[ValueIndex], TableName]));
    493         end;
    494       end else raise Exception.Create(Format(STableNotFound, [TableName]));
     528  end else WhereValues := nil;
     529
     530  if TableName = 'Model' then begin
     531    Table := Tables.SearchByName(WhereValues.Values['Name']);
     532    if Assigned(Table) then begin
     533      Tables.Remove(Table);
     534    end else raise Exception.Create(Format(STableNotFound, [whereValues.Values['Name']]));
     535  end else
     536  if TableName = 'ModelField' then begin
     537    Table := Tables.SearchByName(WhereValues.Values['Model']);
     538    if Assigned(Table) then begin
     539      Field := Table.Fields.SearchByName(WhereValues.Values['Name']);
     540      if Assigned(Field) then begin
     541        Table.Fields.Remove(Field);
     542      end else raise Exception.Create(Format(SFieldNotFound, [WhereValues.Values['Name']]));
     543    end else raise Exception.Create(Format(STableNotFound, [WhereValues.Values['Model']]));
     544  end else begin
     545    Table := Tables.SearchByName(TableName);
     546    if Assigned(Table) then begin
     547      Row := Table.Records.SearchByValues(WhereValues);
     548      if Assigned(Row) then begin
     549        Table.Records.Remove(Row);
     550      end else raise Exception.Create('Row not found');
     551    end else raise Exception.Create(Format(STableNotFound, [TableName]));
     552  end;
     553
     554  if Assigned(WhereValues) then WhereValues.Free;
     555end;
     556
     557procedure TDatabaseXML.QueryUpdate(Text: string; DbRows: TDbRows);
     558var
     559  TableName: string;
     560  Table: TTable;
     561  Row: TRecord;
     562  WhereValues: TStringList;
     563  Field: TField;
     564  Values: TStringList;
     565  ValueIndex: Integer;
     566  FieldIndex: Integer;
     567  ValueName: string;
     568begin
     569  TableName := GetNextPart(Text);
     570  Expect(Text, 'SET');
     571  Values := TStringList.Create;
     572  ValueName := GetNextPart(Text);
     573  Expect(Text, '=');
     574  Values.Add(ValueName + Values.NameValueSeparator + GetNextPart(Text));
     575  while CheckNext(Text, ',') do begin
     576    ValueName := GetNextPart(Text);
     577    Expect(Text, '=');
     578    Values.Add(ValueName + Values.NameValueSeparator + GetNextPart(Text));
     579  end;
     580
     581  if CheckNext(Text, 'WHERE') then begin
     582    WhereValues := TStringList.Create;
     583    ValueName := GetNextPart(Text);
     584    Expect(Text, '=');
     585    WhereValues.Add(ValueName + WhereValues.NameValueSeparator + GetNextPart(Text));
     586    while CheckNext(Text, ',') do begin
     587      ValueName := GetNextPart(Text);
     588      Expect(Text, '=');
     589      WhereValues.Add(ValueName + WhereValues.NameValueSeparator + GetNextPart(Text));
    495590    end;
    496     InsertValues.Free;
     591  end else WhereValues := nil;
     592
     593  if TableName = 'Model' then begin
     594    Table := Tables.SearchByName(WhereValues.Values['Name']);
     595    if Assigned(Table) then begin
     596      //Table.Name := Values.Values['Name'];
     597      if Values.IndexOfName('Caption') <> -1 then
     598        Table.Caption := Values.Values['Caption'];
     599    end else raise Exception.Create(Format(STableNotFound, [WhereValues.Values['Name']]));
    497600  end else
    498   if Command = 'DELETE' then begin
    499     Expect(Text, 'FROM');
    500     TableName := GetNextPart(Text);
    501     if CheckNext(Text, 'WHERE') then begin
    502       WhereName := GetNextPart(Text);
    503       Command := GetNextPart(Text);
    504       if Command = '=' then begin
    505         WhereValue := GetNextPart(Text);
    506       end else raise Exception.Create('Expression error');
    507     end;
    508     if TableName = 'Model' then begin
    509       Table := Tables.SearchByName(WhereValue);
    510       if Assigned(Table) then begin
    511         Tables.Remove(Table);
    512       end else raise Exception.Create(Format(STableNotFound, [whereValue]));
    513     end else
    514     if TableName = 'ModelField' then begin
    515       Field := Table.Fields.SearchByName(WhereName);
    516       Table.Fields.Remove(Field);
    517     end else begin
    518       Table := Tables.SearchByName(TableName);
    519       if Assigned(Table) then begin
    520         Row := Table.Records.SearchByValue(WhereName, WhereValue);
    521         if Assigned(Row) then begin
    522           Table.Records.Remove(Row);
    523         end else raise Exception.Create('Row not found');
    524       end else raise Exception.Create(Format(STableNotFound, [TableName]));
    525     end;
    526   end else
    527     raise Exception.Create(Format(SUnsupportedSqlCommand, [Command]));
     601  if TableName = 'ModelField' then begin
     602    Table := Tables.SearchByName(WhereValues.Values['Model']);
     603    if Assigned(Table) then begin
     604      Field := Table.Fields.SearchByName(WhereValues.Values['Name']);
     605      if Assigned(Field) then begin
     606        if Values.IndexOfName('Name') <> -1 then
     607          Field.Name := Values.Values['Name'];
     608        if Values.IndexOfName('Caption') <> -1 then
     609          Field.TextBefore := Values.Values['Caption'];
     610        if Values.IndexOfName('DataType') <> -1 then
     611          Field.DataType := DbManager.DataTypes.SearchByName(Values.Values['DataType']);
     612      end else raise Exception.Create(Format(SFieldNotFound, [WhereValues.Values['Name']]));
     613    end else raise Exception.Create(Format(STableNotFound, [WhereValues.Values['Model']]));
     614  end else begin
     615    Table := Tables.SearchByName(TableName);
     616    if Assigned(Table) then begin
     617      Row := Table.Records.SearchByValues(WhereValues);
     618      for ValueIndex := 0 to Values.Count - 1 do begin
     619        Field := Table.Fields.SearchByName(Values.Names[ValueIndex]);
     620        if Assigned(Field) then begin
     621          FieldIndex := Table.Fields.IndexOf(Field);
     622          TValue(Row.Values[FieldIndex]).SetString(Values.ValueFromIndex[ValueIndex]);
     623        end else raise Exception.Create(Format(SColumnNotFoundInTable,
     624          [Values.Names[ValueIndex], TableName]));
     625      end;
     626    end else raise Exception.Create(Format(STableNotFound, [TableName]));
     627  end;
     628
     629  if Assigned(WhereValues) then WhereValues.Free;
     630  Values.Free;
     631end;
     632
     633procedure TDatabaseXML.Query(Text: string; DbRows: TDbRows = nil);
     634var
     635  Command: string;
     636begin
     637  Command := GetNextPart(Text);
     638  if Command = 'SELECT' then QuerySelect(Text, DbRows)
     639  else if Command = 'INSERT' then QueryInsert(Text, DbRows)
     640  else if Command = 'DELETE' then QueryDelete(Text, DbRows)
     641  else if Command = 'UPDATE' then QueryUpdate(Text, DbRows)
     642  else raise Exception.Create(Format(SUnsupportedSqlCommand, [Command]));
    528643end;
    529644
Note: See TracChangeset for help on using the changeset viewer.