146
// identifiers_concat {{{
151
} IdentifiersConcatItem;
154
IdentifiersConcatItem **vals;
157
} IdentifiersConcatList;
159
static void identifiers_concat_step(sqlite3_context *context, int argc, sqlite3_value **argv) {
160
const char *key, *val;
162
IdentifiersConcatList *list;
166
list = (IdentifiersConcatList*) sqlite3_aggregate_context(context, sizeof(*list));
167
if (list == NULL) return;
169
if (list->vals == NULL) {
170
list->vals = (IdentifiersConcatItem**)calloc(100, sizeof(IdentifiersConcatItem*));
171
if (list->vals == NULL) return;
176
if (list->count == list->length) {
177
list->vals = (IdentifiersConcatItem**)realloc(list->vals, list->length + 100);
178
if (list->vals == NULL) return;
179
list->length = list->length + 100;
182
list->vals[list->count] = (IdentifiersConcatItem*)calloc(1, sizeof(IdentifiersConcatItem));
183
if (list->vals[list->count] == NULL) return;
185
key = (char*) sqlite3_value_text(argv[0]);
186
val = (char*) sqlite3_value_text(argv[1]);
187
if (key == NULL || val == NULL) {return;}
188
len = strlen(key) + strlen(val) + 1;
190
list->vals[list->count]->val = (char*)calloc(len+1, sizeof(char));
191
if (list->vals[list->count]->val == NULL) return;
192
snprintf(list->vals[list->count]->val, len+1, "%s:%s", key, val);
193
list->vals[list->count]->length = len;
195
list->count = list->count + 1;
200
static void identifiers_concat_finalize(sqlite3_context *context) {
201
IdentifiersConcatList *list;
202
IdentifiersConcatItem *item;
206
list = (IdentifiersConcatList*) sqlite3_aggregate_context(context, sizeof(*list));
207
if (list == NULL || list->vals == NULL || list->count < 1) return;
209
for (i = 0; i < list->count; i++) {
210
sz += list->vals[i]->length;
212
sz += list->count; // Space for commas
213
ans = (char*)calloc(sz+2, sizeof(char));
214
if (ans == NULL) return;
218
for (i = 0; i < list->count; i++) {
219
item = list->vals[i];
220
if (item == NULL || item->val == NULL) continue;
221
memcpy(pos, item->val, item->length);
228
*(pos-1) = 0; // Remove trailing comma
229
sqlite3_result_text(context, ans, -1, SQLITE_TRANSIENT);
145
236
MYEXPORT int sqlite3_extension_init(
146
237
sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){
147
238
SQLITE_EXTENSION_INIT2(pApi);
148
239
sqlite3_create_function(db, "sortconcat", 2, SQLITE_UTF8, NULL, NULL, sort_concat_step, sort_concat_finalize);
149
240
sqlite3_create_function(db, "sort_concat", 2, SQLITE_UTF8, NULL, NULL, sort_concat_step, sort_concat_finalize2);
241
sqlite3_create_function(db, "identifiers_concat", 2, SQLITE_UTF8, NULL, NULL, identifiers_concat_step, identifiers_concat_finalize);