AnyDAC
ContentsIndexHome
PreviousUpNext
SQLite Database Questions

The list of questions and answers related to SQLite Database.

Group
Links
QL1: How can I define collate sequence in SQLite DB?

A: There are completed collations, functions, extensions API's and demos. Check "Demos\DBMS Specific\SQLite\UserCollation". 

If you need collations / functions at design-time make design-time package (fake component) where you register user collations / functions. 

 

QL2: SQLite exception "[AnyDAC][DApt]-401. Record is locked by another user."

A: The exception is raised on UPDATE command, when another DB connection has cursor on the same table and not all records are fetched from it. You must use FetchOptions.Mode=fmAll. Even you can set this option at ADConnection level, so all linked to it datasets will inherit this option. 

 

QL3: Data type for non-table SELECT list item is wrong ? (or) My aggregated function returns string value. What is wrong ?

A: SQLite does not return a data type for non-table SELECT list items. IOW, if an item is an expression, then AnyDAC cannot get it data type. So, it just describes it as ftWideString. AnyDAC has ability to specify SELECT item data type: <item> as "<alias>::<data type>". For example: 

 

SELECT count(*) as "cnt::int" from ...

 

QL4: It seems that character macro are not supported with SQLite? I try with CONCAT, LEFT, SUBSTR, UCASE, ..

A: These functions are implemented using AnyDAC expression evaluator. When you are creating a connection at run-time, you should include uADStanExprFuncs.pas into "uses" clause. 

SQLite has a limited set of build-in functions. But it allows to write and register custom functions. AnyDAC has many custom functions implemented for the expression evaluator. They implementations and registrations are in ADStanExprFuncs. SQLite driver automatically registers all known expression evaluator functions with sqlite3.dll. 

 

QL5: Is sqlite3_progress_handler implemented with AnyDAC ?

A: Yes. Use the code like that: 

 

procedure Tform1.FormCreate(Sender: TObject);
begin
  ADConnection1.Open;
  with TSQLiteDatabase(ADConnection1.ConnectionIntf.CliObj) do
  begin
    ProgressNOpers := 50000;
    OnProgress := SQLiteOnProgress;
  end;
end;

procedure Tform1.SQLiteOnProgress(ADB: TSQLiteDatabase; var ACancel: Boolean);
begin
  Application.ProcessMessages;
end;

 

QL6: Our WAL files are getting huge (>1 GB) when working with our multi-threaded application. Do you have any suggestion on how to prevent WAL files from growing?

A: If WAL file keeps growing that means it’s impossible to move data from the log into the database file. Probably the database is permanently used by reading threads and/or there are performed DML operations without committing a transaction. The possible solutions in this case are to use only short transactions or to create a separate thread for DML operations (in this case transactions should also be constantly committed). 

If a checkpoint runs and copies all WAL data into the database file, the next writer starts writing into the start of the WAL file again. The WAL file is not usually truncated (see PRAGMA journal_size_limit if you want it to be) here. The reason being that it is faster to overwrite an existing file than it is to truncate one and then start appending to it. 

So, if all goes well, SQLite should start over at the start of the WAL file after each checkpoint. Preventing the WAL file from growing indefinitely. There are two things that can go wrong:

  • A reader might prevent a check-pointer from copying all data from the WAL into the database file, or
  • While the checkpoint is underway, some other process may be writing to the database (appending to the WAL file).

If either of the above occurs, then the next writer will append to the WAL file, instead of writing into the start of it. If this happens every checkpoint, then the WAL file will grow without bound.

What do you think about this topic? Send feedback!