{ Simple example of how to build a loadable extension with DISQLite3. It shows
  a single collation sequence which sorts by reversed byte order. Extensions
  are not limited to creating a collating sequence or function. A real loadable
  extension would probably do something more useful.

  Note that the extension uses the "DISQLite3Ext" unit instead of
  "DISQLite3Api". This is an important difference. Dynamically loaded extensions
  should always use "DISQLite3Ext" and statically linked additions to an
  application should use "DISQLite3Api".

  If you want your code to work as either a statically linked or a dynamically
  loaded module, the you will need to use $IFDEFS to use the appropriate unit.}
library DISQLite3_Extension_Collate_Reverse;

{$I DICompilers.inc}
{$I DISQLite3.inc}

uses
  {$IFDEF FastMM}{$I FastMM_uses.inc}{$ENDIF}
  {$IFDEF HAS_UNITSCOPE}
  System.SysUtils, System.AnsiStrings,
  {$ELSE HAS_UNITSCOPE}
  SysUtils,
  {$ENDIF HAS_UNITSCOPE}
  DISystemCompat, DISQLite3Ext; // Use the extension type definitions.

{ This variable stores the set of DISQLite3 API functions and procedures. The
  variable name "DISQLite3Api" is choosen on purpose so it is easier to reuse
  this code inside a regular, non-extension project. }
var
  DISQLite3Api: sqlite3_api_routines_ptr;

  //----------------------------------------------------------------------------

{ The "reverse" collating sequence compares by byte order and reverses the
  result. }
function CompareReverse_func(
  UserData: Pointer;
  l1: Integer;
  const s1: Pointer;
  l2: Integer;
  const s2: Pointer): Integer;
begin
  { Compare the strings ... }

  Result := {$IFDEF DEPRECATED_SYSUTILS_ANSISTRINGS}System.AnsiStrings.{$ENDIF}
  StrComp(PUtf8Char(s1), PUtf8Char(s2));

  { ... and reverse the sort order. }
  if Result < 0 then
    Result := 1
  else
    if Result > 0 then
      Result := -1;
end;

//------------------------------------------------------------------------------

{ This is the extension entry point and is usually the only exported function in
  a DISQLite3 loadable library. DISQLite3 invokes this function once when it
  loads the extension.

  Use this function to create new functions, collating sequences, and virtual
  table modules. }
function sqlite3_extension_init(
  DB: sqlite3_ptr;
  pzErrMsg: PPAnsiChar;
  pApi: sqlite3_api_routines_ptr): Integer;
begin
  { Store the set of published API functions and procedures to the
    "DISQLite3Api" variable. }
  DISQLite3Api := pApi;
  { Register the "reverse" collation sequence. }
  DISQLite3Api.sqlite3_create_collation_v2(
    DB, 'reverse', SQLITE_UTF8, nil, CompareReverse_func, nil);
  { Return success. }
  Result := SQLITE_OK;
end;

exports
  sqlite3_extension_init;

begin
  {$IFDEF FastMM}{$I FastMM_init.inc}{$ENDIF}
  // Nothing to initialize here.
end.

