KDb

SqliteFunctions.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2015 Jarosław Staniek <staniek@kde.org>
3
4 Contains portions of sqlite3.c licensed under public domain. The author disclaims
5 copyright to this source code.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21*/
22
23#include "SqliteFunctions.h"
24
25#include <QDebug>
26
27#include <cctype>
28
29/*
30** Integers of known sizes. These typedefs might change for architectures
31** where the sizes very. Preprocessor macros are available so that the
32** types can be conveniently redefined at compile-type. Like this:
33**
34** cc '-DUINTPTR_TYPE=long long int' ...
35*/
36#ifndef UINT32_TYPE
37# ifdef HAVE_UINT32_T
38# define UINT32_TYPE uint32_t
39# else
40# define UINT32_TYPE unsigned int
41# endif
42#endif
43#ifndef UINT16_TYPE
44# ifdef HAVE_UINT16_T
45# define UINT16_TYPE uint16_t
46# else
47# define UINT16_TYPE unsigned short int
48# endif
49#endif
50#ifndef INT16_TYPE
51# ifdef HAVE_INT16_T
52# define INT16_TYPE int16_t
53# else
54# define INT16_TYPE short int
55# endif
56#endif
57#ifndef UINT8_TYPE
58# ifdef HAVE_UINT8_T
59# define UINT8_TYPE uint8_t
60# else
61# define UINT8_TYPE unsigned char
62# endif
63#endif
64#ifndef INT8_TYPE
65# ifdef HAVE_INT8_T
66# define INT8_TYPE int8_t
67# else
68# define INT8_TYPE signed char
69# endif
70#endif
71#ifndef LONGDOUBLE_TYPE
72# define LONGDOUBLE_TYPE long double
73#endif
74typedef sqlite_int64 i64; /* 8-byte signed integer */
75typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
76typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
77typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
78typedef INT16_TYPE i16; /* 2-byte signed integer */
79typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
80typedef INT8_TYPE i8; /* 1-byte signed integer */
81
82static bool tryExec(sqlite3 *db, const char *sql)
83{
84 return SQLITE_OK == sqlite3_exec(db, sql, nullptr /*callback*/,
85 nullptr /* 1st argument to callback */, nullptr /*err*/);
86}
87
88// BEGIN from sqlite3.c
89#define sqlite3Toupper(x) toupper((unsigned char)(x))
90#define sqlite3Isalpha(x) isalpha((unsigned char)(x))
91
92/*
93** Compute the soundex encoding of a word.
94**
95** IMP: R-59782-00072 The soundex(X) function returns a string that is the
96** soundex encoding of the string X.
97*/
98static void soundexFunc(
99 sqlite3_context *context,
100 int argc,
101 sqlite3_value **argv
102){
103 char zResult[8];
104 const u8 *zIn;
105 int i, j;
106 static const unsigned char iCode[] = {
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
112 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
113 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
114 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
115 };
116 assert( argc==1 );
117 zIn = (u8*)sqlite3_value_text(argv[0]);
118 if( zIn==0 ) zIn = (u8*)"";
119 for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){}
120 if( zIn[i] ){
121 u8 prevcode = iCode[zIn[i]&0x7f];
122 zResult[0] = sqlite3Toupper(zIn[i]);
123 for(j=1; j<4 && zIn[i]; i++){
124 int code = iCode[zIn[i]&0x7f];
125 if( code>0 ){
126 if( code!=prevcode ){
127 prevcode = code;
128 zResult[j++] = code + '0';
129 }
130 }else{
131 prevcode = 0;
132 }
133 }
134 while( j<4 ){
135 zResult[j++] = '0';
136 }
137 zResult[j] = 0;
138 sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
139 }else{
140 /* IMP: R-64894-50321 The string "?000" is returned if the argument
141 ** is NULL or contains no ASCII alphabetic characters. */
142 sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
143 }
144}
145
146bool createCustomSQLiteFunctions(sqlite3 *db)
147{
148 int eTextRep = SQLITE_UTF8;
149#if SQLITE_VERSION_NUMBER >= 3008003
150 eTextRep |= SQLITE_DETERMINISTIC;
151#endif
152 if (!tryExec(db, "SELECT SOUNDEX()")) {
153 int res = sqlite3_create_function_v2(
154 db,
155 "SOUNDEX",
156 1, //nArg
157 eTextRep,
158 nullptr, // pApp
159 soundexFunc,
160 nullptr, // xStep
161 nullptr, // xFinal
162 nullptr // xDestroy
163 );
164 if (res != SQLITE_OK) {
165 return false;
166 }
167 }
168 return true;
169}
170
171// END from sqlite3.c
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:59 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.