[Solved] SQLite - multiuser access lazarus / 16-Databases ---------------------------------------------------------------------- Milsa · 2021-02-10 11:29 I need to edit my SQLite application. The current state is this: - start application - backup sqlite database (if application is opened from another computer, this operation break application (I am using standard copy method for file)) - working My idea is this: - start application - test for open application from another computer (how?) - if it is open set access to read - if it is not open set access to write and backup database (maybe with stream method (application does not raise exception)) This is easy if I insert information about open to database or config file and I remove this information if I quit the application. But if my application craches then I do not remove information about write access from database or config file and application will be not accessed for write anymore. Therefore, I need to find out the computer identifier (how?) so that the same computer can still have write access when I restart the application. Does exists easier way? My application need Windows. Multiplatform solution is welcome for future and other projects. I need only one access for write in the same time from same instance of application on same computer. Other will be access for read only. ---------------------------------------------------------------------- ASerge · 2021-02-10 12:48 Quote from: Milsa on February 10, 2021, 12:29:00 pm...or config file... My application need Windows... Open the configuration file with the request "read and write, share deny write". The application that was able to open the file with such a request is the first one. When the application is closed (even if it crashes), Windows will close all open files. ---------------------------------------------------------------------- Zvoni · 2021-02-10 14:41 An "easy" way would be to create a "lock"-file (like Excel or Word does) 1) User starts App and checks for lock-File. If it doesn't exist, create a Lock-File and store HostName of Computer and Username of User inside, open Database for Read/Write 1b) When user closes Database delete Lock-File 2) Another User on another machine starts the app and checks for Lock- file, and finds it. Read the Lock-File (to get the Info who has it open), and open Database for Read only 2b) This user never deletes the Lock-file No idea about clean-up if app which created the lock-file crashes ---------------------------------------------------------------------- Milsa · 2021-02-10 15:40 Quote from: ASerge on February 10, 2021, 01:48:12 pmQuote from: Milsa on February 10, 2021, 12:29:00 pm...or config file... My application need Windows... Open the configuration file with the request "read and write, share deny write". The application that was able to open the file with such a request is the first one. When the application is closed (even if it crashes), Windows will close all open files. This is nice solution. How can I open file with this permission and how to test it from another computer? I do not know all methods for open files. I am using old standard methods. ---------------------------------------------------------------------- ASerge · 2021-02-10 17:43 Quote from: Milsa on February 10, 2021, 04:40:08 pmHow can I open file with this permission and how to test it from another computer? Application for test: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE OBJFPC}{$LONGSTRINGS ON}{$APPTYPE CONSOLE} uses Windows; type  TOpenResult = (orDeny, orReadWrite, orReadOnly); // orReadWrite = Created function OpenFile(const FileName: string): TOpenResult;   function DoCreate(DesiredAccess, ShareMode, CreationDisposition: DWORD): THandle;  begin    Result := CreateFileW(      PWideChar(UTF8Decode(FileName)),      DesiredAccess,      ShareMode,    nil,      CreationDisposition,      0, 0);  end;   function Lock(HFile: THandle; Offset: QWORD; Count: DWORD = 1): Boolean;  var  R: OVERLAPPED;  begin    ZeroMemory(@R, SizeOf(R));    R.OffsetHigh := Hi(Offset);    R.Offset := Lo(Offset);    Result := LockFileEx(HFile,      LOCKFILE_EXCLUSIVE_LOCK or LOCKFILE_FAIL_IMMEDIATELY,      0, // Reserved      Count, 0, // Count bytes to lock      @R);  end; const  CMaxOpenUsers = 100;  CStartOffset = High(Int64) - CMaxOpenUsers - 1;   function LockAny(HFile: THandle): Boolean;  var    i: DWORD;  begin    for i := 0 to CMaxOpenUsers - 1 do      if Lock(HFile, CStartOffset + i) then      Exit(True);    Result := False;  end;   function LockAll(HFile: THandle): Boolean;  begin    Result := Lock(HFile, CStartOffset, CMaxOpenUsers);    if Result then      UnlockFile(HFile, Lo(CStartOffset), Hi(CStartOffset), CMaxOpenUsers, 0);  end; var  HFile: THandle;  Err: DWORD;begin  HFile := DoCreate(GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, OPEN_ALWAYS);  if HFile <> INVALID_HANDLE_VALUE then  begin    if LockAll(HFile) then      Exit(orReadWrite);    CloseHandle(HFile);  end;  HFile := DoCreate(GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, OPEN_EXISTING);  if HFile <> INVALID_HANDLE_VALUE then  begin    if LockAny(HFile) then      Exit(orReadOnly);  end;  Err := GetLastError;  Writeln('GetLastError is ', Err);  Result := orDeny;end; procedure TestOpenFile(const FileName: string);begin  Writeln('Opening ', FileName, '...');  case OpenFile(FileName) of    orDeny:      Writeln('Deny');    orReadWrite:      Writeln('First. Opened as read-write');    orReadOnly:      Writeln('NOT first. Opened as read-only');  end;  // File stay openedend; var  FileName: string;begin  FileName := ParamStr(1);  if FileName = '' then    FileName := 'lock.txt';  TestOpenFile(FileName);  Readln;end. ---------------------------------------------------------------------- Milsa · 2021-02-10 19:34 Thank you. This is easy method. I will try this code. ---------------------------------------------------------------------- Milsa · 2021-02-12 12:01 Thanks. This solution is usable for me. Solved for Windows.