Diacritical folding can be directly achieved in SQLite by implementing a custom function call. The following code demonstrates a possible implementation of such a function, taking in a string and returning a copy of the string with its diacritical marks folded.
#include <stdlib.h>
#include <sqlite3.h>
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
// this will be called by sqlite to dispose of the memory we malloced in diactrics_folding
void destruct_result(void * ptr)
{
free(ptr);
}
void diactrics_folding(sqlite3_context* ctx,int cnt,sqlite3_value** val)
{
char * in = (char *)sqlite3_value_text(*val);
if(in == NULL)
return;
CFStringRef cstr = CFStringCreateWithCString(NULL, in, kCFStringEncodingUTF8);
CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 0, cstr);
CFStringFold(str, kCFCompareDiacriticInsensitive, NULL);
char * resultAsCString = malloc(strlen(in));
if(!CFStringGetCString(str, resultAsCString, strlen(in), kCFStringEncodingUTF8))
{
free(resultAsCString);
sqlite3_result_text(ctx, in, strlen(in), NULL);
return;
}
sqlite3_result_text(ctx, resultAsCString, strlen(resultAsCString), &destruct_result);
CFRelease(cstr);
CFRelease(str);
}
int cback (void* udata,int ncol,char** value,char** colname)
{
int i=0;
for(;i<ncol;i++)
printf("Result column: %s value: %s \n", colname[i], value[i]);
return 0;
}
int main()
{
sqlite3 * handle;
int res = sqlite3_open("./test.sql", &handle);
res = sqlite3_create_function(handle, "diactrics_folding", 1, SQLITE_UTF8, NULL, &diactrics_folding, NULL, NULL);
char * errmsg = NULL;
res = sqlite3_exec(handle, "select w, diactrics_folding(w) from t", &cback, NULL, &errmsg);
printf("sqlite3_exec result: %d %s\n", res, errmsg != NULL ? errmsg : "No error");
sqlite3_close(handle);
}
diciu$ gcc sqlite_diacritics.c -framework CoreFoundation -lsqlite3
diciu$ ./a.out
Result column: w value: mămăliguță cu brânză și smântână
Result column: diactrics_folding(w) value: mamaliguta cu branza si smantana
sqlite3_exec result: 0 No error