#1 Yesterday 12:10:18

George
Member
Registered: 2016-04-05
Posts: 144

SQLite error in Linux

Hello!

Probably I'm doing something wrong, but not sure.
I have test project that works on windows and Linux, however, Linux version quickly become unusable because of a AV errors.

Here is full project files and test script.
How to use:
1. Start app from dist\project1\debug\
2. Open 4 copies of TestPage.html in the browser.
3. Wait.

Windows version will work without any problems, doesn't matter how long.
Linux version will become buggy pretty quick.

html page makes request to application each second.
Application calls ReadData method.

unit SqliteLinuxFreeze;

{$mode delphi}
{$WRITEABLECONST OFF}

interface

uses
  Classes,
  SysUtils,
  LazFileUtils,
  mormot.core.base,
  mormot.core.Data,
  mormot.core.datetime,
  mormot.core.Text,
  mormot.core.unicode,
  mormot.core.log,
  mormot.core.variants,
  mormot.DB.raw.sqlite3,
  mormot.DB.raw.sqlite3.static;

type

  { TSQLite }

  TSQLite = class(TMultiReadExclusiveWriteSynchronizer)
  private
    SQLite: TSQLDataBase;
  public
    constructor Create(); override;
    destructor Destroy(); override;
    function ReadData(): boolean;
  end;

var
  SQLiteService: TSQLite = nil;

implementation

{ TSQLite }

constructor TSQLite.Create();
var
  DBPath: RawUtf8;
  DBPresent: Boolean;
begin
  inherited Create();
  DBPath := ConcatPaths([AppendPathDelim(ExtractFileDir(ParamStr(0))), 'db.sqlite']);
  DBPresent := FileExistsUTF8(DBPath);
  SQLite := TSQLDataBase.Create(DBPath, 'mormot', SQLITE_OPEN_READWRITE or SQLITE_OPEN_CREATE or SQLITE_OPEN_FULLMUTEX);
  // Create tables and test data
  if not DBPresent then
    begin
      SQLite.Execute('CREATE TABLE metadata (key TEXT PRIMARY KEY NOT NULL, value TEXT) STRICT;');
      SQLite.Execute('INSERT INTO metadata VALUES (''someField'', ''SomeValue'');');
    end;
end;

destructor TSQLite.Destroy();
begin
  if Assigned(SQLite) then
    SQLite.Free;
  inherited Destroy();
end;

function TSQLite.ReadData: boolean;
var
  SQLRq: TSQLRequest;
  Value: RawUTF8;
begin
  Result := False;
  Value := '';
   try
    Beginread;
     try
       try
        SQLRq.Prepare(SQLite.DB, 'SELECT value FROM metadata where key= :key');
        SQLRq.Bind(1, 'someField');
        if SQLRq.Step = SQLITE_ROW then
          begin
            SQLRq.FieldUTF8(0, Value);
            if Value = 'SomeValue' then
              Result := True;
          end;
       finally
        SQLRq.Close;
       end;
     except
      on E: Exception do
        WriteLn(E.Message);
     end;
   finally
    Endread;
   end;
end;

end.

Offline

#2 Yesterday 13:20:02

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,324
Website

Re: SQLite error in Linux

Don't use TMultiReadExclusiveWriteSynchronizer to secure a TSQLDatabase instance.
There is already TSQLDatabase.Lock/UnLock or LockJson/UnLockJson for this.

Offline

#3 Yesterday 15:12:20

George
Member
Registered: 2016-04-05
Posts: 144

Re: SQLite error in Linux

Thanks, with the switch to TSQLDatabase.Lock/UnLock it works smile
I will run tests for extra 12H on windows and Linux to be sure.

Offline

Board footer

Powered by FluxBB