#1 2015-07-28 19:33:31

zed
Member
From: Belarus
Registered: 2015-02-26
Posts: 105

Bug: MongoDB + UpdateField

With MongoDB as a backend, TSQLRestClient.UpdateField() generate bad request and always replace whole document:

{collection:"MyDB.MyColl",opCode:"opUpdate",requestID:41,selector:{_id:1},update:{MyField:1}}

Correct request should use $set keyword:

{collection:"MyDB.MyColl",opCode:"opUpdate",requestID:41,selector:{_id:1},update:{$set:{MyField:true}}}

Please, fix it.

Offline

#2 2015-07-29 08:36:36

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Bug: MongoDB + UpdateField

Shoud be fixed by http://synopse.info/fossil/info/61703a9a3c

Thanks for the report.

Offline

#3 2015-08-03 18:53:25

zed
Member
From: Belarus
Registered: 2015-02-26
Posts: 105

Re: Bug: MongoDB + UpdateField

New bug: if we try update text field with "\" symbol it's erase this symbol:

VStr := StringToUTF8('Test string\with slash\with 2 slashes');
VRes := VClientDB.UpdateField(TTestDoc, VDoc.ID, 'Field1', [VStr]);
TSQLRestServerDB(023D6D40).URI(PUT root/TestDoc?setname=Field1&set=%22Test+string%5Cwith+slash%5Cwith+2+slashes%22&wherename=RowID&where=1 inlen=0)
{collection:"test.TestDoc",opCode:"opUpdate",requestID:7,selector:{_id:1},update:{$set:{Field1:"Test stringwith slashwith 2 slashes"}}}

Test code:

uses
  mORMot,
  mORMotSQLite3,
  mORMotMongoDB,
  SynMongoDB,
  SynSQLite3Static,
  SynCommons;

type
  TTestDoc = class(TSQLRecord)
  private
    FField1: RawUTF8;
    FField2: Int64;
  published
    property Field1: RawUTF8 read FField1 write FField1;
    property Field2: Int64 read FField2 write FField2;
  end;

procedure TestUpdateField;
var
  VRes: Boolean;
  VStr: RawUTF8;
  VDoc: TTestDoc;
  VModel: TSQLModel;
  VClient: TMongoClient;
  VDatabase: TMongoDatabase;
  VClientDB: TSQLRestClientDB;
begin
  VClient := TMongoClient.Create('127.0.0.1', 27017);
  try
    VDatabase := VClient.Open('test');
    VModel := TSQLModel.Create([TTestDoc]);
    try
      VClientDB := TSQLRestClientDB.Create(VModel, nil, ':memory:', TSQLRestServerDB);
      try
        if not StaticMongoDBRegisterAll(VClientDB.Server, VDatabase) then begin
          Exit;
        end;

        VClientDB.Server.CreateMissingTables;

        VDoc := TTestDoc.Create;
        try
          VStr := StringToUTF8('Test string\with slash');

          VDoc.FField1 := VStr;
          VDoc.FField2 := 123456;

          if not (VClientDB.Add(VDoc, True) > 0) then begin
            Assert(False);
            Exit;
          end;

          VStr := StringToUTF8('Test string\with slash\with 2 slashes');
          VRes := VClientDB.UpdateField(TTestDoc, VDoc.ID, 'Field1', [VStr]);

          Assert(VRes);

          VRes := VClientDB.Retrieve(VDoc.ID, VDoc);

          Assert(VRes);

          Assert(VDoc.FField1 = VStr);
          Assert(VDoc.FField2 = 123456);
        finally
          VDoc.Free;
        end;
      finally
        VClientDB.Free;
      end;
    finally
      VModel.Free;
    end;
  finally
    VClient.Free;
  end;
end;

In same time, method TSQLRestClient.Update() is save correct text with all slashes.

Last edited by zed (2015-08-03 18:55:24)

Offline

#4 2015-08-04 09:22:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Bug: MongoDB + UpdateField

You should write \\ instead of \ in the field input, on your side.
This is how it is expected to work.

Offline

#5 2015-08-04 09:42:04

zed
Member
From: Belarus
Registered: 2015-02-26
Posts: 105

Re: Bug: MongoDB + UpdateField

Why I should use different strings in Update() and UpdateField() methods? I think that behaviour in this methods must be the same.
Besides that, with SQLite3 or DBMS, UpdateField() works fine, error only with MongoDB, and if I wish use the same code with SQLite3 and MongoDB, I should use \\ or \ depends on the DB backend? I think that it's bad idea.

In any case, I decided not to use UpdateField() method in my code anymore.

Offline

Board footer

Powered by FluxBB