User collation routines

Collation routines can be used to order results from a SELECT statement. You can provide your own routine, and tell qdb to use it by providing the COLLATE keyword to the ORDER BY clause.

These routines are specified in the database configuration object with the Collation::tag@library.so option, where tag is the name of the struct qdb_collation entry describing the collation, and library.so is the name of a DLL object containing your code (this can be an absolute path or a relative path within the library search path). This is set up as follows:

static int mysort(void *arg, int l1, 
                  const void *s1, int l2, const void *s2)
{
    return(0);
}

struct qdb_collation ctag = { 
    "nosort", SQLITE_UTF8, NULL, mysort, NULL };

The tag value in this case is ctag, the collation name as visible to SQL is nosort, and the C function that implements your collation routine is called is mysort(), which is passed in the third field (here NULL) as its arg argument (refer to SQLite docs on sqlite3_create_collation() for more detail).

Note: The ctag was used to clarify the example. You would probably use the name nosort here so it was the same as the SQL name.

There can be multiple collation sequences defined (in the same or different DLLs), but each must have a Collation:: entry in the configuration object, and each must have a struct qdb_collation of a unique name describing it.

The qdb_collation structure has these members:

struct qdb_collation {
  char  *name;
  int   encoding;
  void  *arg;
  int   (*compare)(void *, int, const void *, int, const void *);
  int   (*setup)(void *, const void *, int, char **);
};
name
The name used for this function in SQL statements. This is limited to 255 bytes, exclusive of the zero-terminator, and it can't contain any special tokens, or start with a digit. Any attempt to create a function with an invalid name will result in an SQLITE_ERROR error.
encoding
The character encoding of strings passed to your function. Can be one of:
  • SQLITE_UTF8
  • SQLITE_UTF16
  • SQLITE_UTF16BE
  • SQLITE_UTF16LE
arg
An arbitrary pointer to user data that is passed as the first argument to your function each time it's invoked. The function implementations can gain access to this pointer using the sqlite_user_data() API.
compare
A pointer to your collation function.
setup
A pointer to a setup function to allow dynamic configuration of sort order at runtime. See below.

The setup function takes this form:

int (*setup)(void *arg, const void *data, 
             int nbytes, char **errmsg);

The parameters of the setup function are:

void *arg
The context pointer. This is the same as the arg to the compare function, and is passed in from the arg element of the qdb_collation structure.
const void *data, int nbytes
The configuration data, used to configure the sort. When invoked from startup, this is NULL and 0. When invoked at run time, it is the data provided to the qdb_collation() function. QDB doesn't interpret the format in any way; the DLL must cooperate with the caller of qdb_collation() to exchange data of a known format.
char **errmsg
A pointer to an error message string that is available to qdb_geterrmsg() displayed on failure (actually, from startup QDB will fail it, from runtime qdb_collation() will fail and this string will be available to it as qdb_geterrmsg())

The function should return a POSIX errno value, or EOK if it succeeds.

If a collation entry has a non-NULL setup entry, then this is invoked at startup and passed NULL for data and 0 for nbytes, which it can use as a hint to go into some default configuration. Then, whenever you call qdb_collation(), the setup function is invoked with new data.

If a collation has no dynamic configuration, then it can use a NULL setup entry in the struct qdb_collation, and it can't be dynamically configured.