📄 dbfilter.c
字号:
#include <stdio.h>#include <stdlib.h>#include <glib.h>#include "dbfilter.h"#include "db.h"#include "dbtoliet.h"#include "dbfield.h"static voiddb_filter_freerequest(GList * requestlist) { GList *walk; for (walk = g_list_first(requestlist); walk != NULL; walk = walk->next) mem_free(walk->data); g_list_free(requestlist); }/** * db_filter_free: * * Free filter element in the cache. */gintdb_filter_free(DbFilter * filter) { mem_free(filter); return 0; }/** * db_filter_create: * * Create a filter. */DbFilter *db_filter_create(gboolean active, gint sortedpos) { DbFilter *f; f = mem_alloc(sizeof(DbFilter)); f->active = active; f->sortedpos = sortedpos; return f; }/** * db_filter_createpos: * @obj: * * Goes though and puts the raw posistion in the list, based on if the widget is active * or not. * * Returns: %0 if success. */static gintdb_filter_createpos(Object * obj) { int i, count = 0; g_assert(obj); for (i = 0; i < obj->numcache; i++) { if (obj->cache[i] == NULL) continue; if (obj->cache[i]->filter->active == TRUE) { obj->cache[i]->filter->sortedpos = count; count++; } else obj->cache[i]->filter->sortedpos = -1; } return 0; }/** * db_filter_sortbypos: * @obj: The object to be sorted * @fieldname: The name of the field to be sorted * @tablename: The name of the table that has the field to be sorted * @order_ascending: TRUE if ascending, FALSE if descending * * This sort function is for an object which cache has been loaded. * In other word, use this on an object after you called db_filter_load() on * the object just like when you db_filter_filterbyvalue(). * The reason is that db_filter_load() does cacheing stuff for you. * NOTE: At this moment, the function can only sort on simple numeric integer field. * Written by Francis * Returns: %0 if successful. %-3 if failed to sort (in detail, if this failed * to move very first row **/gintdb_filter_sortbypos (Object *obj, gchar * fieldname, /* Sort by this field */ gchar * tablename, /* Which table the field belong */ gboolean order_ascending){ gint i, j; gint pos; gint count = 0; int validcachecount; int invalidcachecount; gint * idx_array; static int comp (const void *a, const void *b); /* Sort index by its cache array's specified position value */ static int comp (const void *a, const void *b) { gint aa, bb; aa = *((gint*)a); bb = *((gint*)b); /*printf ("comp (%d, %d)\n", aa, bb);*/ return (order_ascending) ? atoi (obj->cache[aa]->value[pos]) - atoi (obj->cache[bb]->value[pos]) : atoi (obj->cache[bb]->value[pos]) - atoi (obj->cache[aa]->value[pos]) ; } /* Assertions */ g_assert (obj); g_assert (fieldname); g_assert (tablename); g_assert (obj->numcache == obj->num); pos = db_field_getpos (obj, fieldname, tablename); puts ("***********************************************"); printf ("Field '%s' position in table '%s'= %dth\n", fieldname, tablename, pos+1); puts ("***********************************************"); puts ("***********************************************"); printf ("Num of cache: %d\n", obj->numcache); puts ("***********************************************"); /* Set the array to be sorted *//* printf ("Number of object cache: %d\n", obj->numcache); */ idx_array = (gint*)mem_alloc (sizeof (gint) * obj->numcache); /* Francis: Ok, here is the story of why I am using valid cache and * chekcing the validity of a cache. Basically, this mechanism is * required when you add a new row. Then suddenly one invalid * row (because this new row hasn't got proper field values yet) * will be sitting at the last row (could be in the middle, hmm). * Thus, we need to skip this row. * * Example: => should change to * Validrow with value 2 Validrow with value 1 * Invalidrow(1) with value ? Validrow with value 2 * Validrow with value 3 Validrow with value 3 * Validrow with value 1 Invalidrow(1) with value ? * Invalidrow(2) with valu ? Invalidrow(2) with value ? * * As you can see above, invalid row should all go to the back of the rows. */ /* Init the array */ invalidcachecount = validcachecount = 0; for (i = 0 ; i < obj->numcache; i++) { /*printf ("cache num[%d]: state(0:READ,1:EDITREAD,2:NEW,3:EDITNEW) => %d, changed => %s\n", i, obj->cache[i]->state, (obj->cache[i]->changed)?"TRUE":"FALSE");*/ /* If the state of the cache is just OBJ_READ (cache just has been read) * or OBJ_EDITREAD (cache has been read and then edited), I assume the * sortting field values already exist with a valid value. */ if ((obj->cache[i]->state == OBJ_READ || obj->cache[i]->state == OBJ_EDITREAD) && obj->cache[i]->value[pos] != NULL) { idx_array[validcachecount++] = i; } else { /* Farncis: Fill invalid cache row from the last index. * I am trying to be clever at this moment. I don't want another * loop only to sort out these invalid cache row. * All this silly thing was derived from my assumption there could be * more than one invalid row. However, it could be useful it the row * allows NULL value */ int lastindex; lastindex = obj->numcache-1; /* Just to clearify */ idx_array[lastindex-invalidcachecount++] = i; } /*printf ("%d's value = %s\n", i, obj->cache[i]->value[pos]);*/ }/* puts("");*/ debugmsg ("Valid number of cache rows: %d", validcachecount); qsort (idx_array, validcachecount, sizeof(gint), comp); /* For each row which has a valid cache field to sort */ for (i = 0; i < validcachecount; i++) { /* Remember that the index array element from 0 to validcachecount-1 * contain sorted indice */ obj->cache[idx_array[i]]->filter->active = TRUE; obj->cache[idx_array[i]]->filter->sortedpos = i; count++; } /* For each row... */ for (i = validcachecount, j = obj->numcache - 1; i < obj->numcache; i++, j--) { obj->cache[idx_array[j]]->filter->sortedpos = i; count++; } for (i = 0; i < obj->numcache; i++) { debugmsg ("row id: %s, sortedpos: %d\n", obj->cache[i]->value[0], obj->cache[i]->filter->sortedpos); }/* if (db_moveto(obj, 0) != 0) { warningmsg("Unable to move to the orginal record."); return -3; }*/ db_filter_checkvisible(obj); return 0;} /** * db_filter_filterbyvalue: * @roof: ehhh * @fieldname: ahhh * @fieldvalue: eeerrr * * given a roof, filter another roof with that filter. i had a whole lot of comments * about how all this worked but i got bored of reading and writing it so i deleted it. * sorry guys.read the code isntead * * Returns: A Number! */gintdb_filter_filterbyvalue(Object * obj, gchar * fieldname, gchar * tablename, gchar * fieldvalue) { gint i, c = 0; gint datapos = -1; gchar *value; g_assert(obj); g_assert(fieldname); g_assert(fieldvalue); obj->currentcache = NULL; debugmsg("Filtering list %s, field %s for value %s", obj->name, fieldname, fieldvalue); if (obj->cache == NULL || obj->numcache <= 0) { errormsg("filter is not set up so can not filter."); return -1; } if (db_iscacheloaded(obj) == FALSE) { errormsg("The cache isn't loaded, you need to load all your records first"); return -2; } db_filter_applied_addfilter(obj,fieldname, tablename, fieldvalue); datapos = db_field_getpos(obj, fieldname, tablename); /* Ohh no its not show, so go load it. Assumes filter and object are in sync */ if (obj->numcache > 0 && datapos >= 0 && obj->cache[0]->flags[datapos] == FILTER_EMPTY) { debugmsg("loading an extra field so i can filter here"); for (i = 0; i < obj->num; i++) { db_moveto(obj, i); if (db_getvalue(obj, fieldname, tablename, &value) != 0) { warningmsg("failed to extract field %s", fieldname); break; } obj->cache[i]->flags[datapos] = FILTER_HIDDEN; } if (obj->num <= 0) debugmsg("zero length list, arr, so can't really filter this"); } for (i = 0; i < obj->numcache; i++) { if (obj->cache[i] == NULL || obj->cache[i]->value[datapos] == NULL) continue; if (strcmp(obj->cache[i]->value[datapos], fieldvalue) == 0) { obj->cache[i]->filter->active = TRUE; c++; } else { obj->cache[i]->filter->active = FALSE; } } db_filter_createpos(obj); db_filter_checkvisible(obj); debugmsg("filter has now been finished, with %d of %d items showing", c, obj->num); return 0; }/** * db_filter_load: * @obj: * @requestlist: * * Move though all records, extract the data as desired by @requestlist. * */gintdb_filter_load(Object * obj, GList * requestlist) { gint i, origrow; gchar *value; GList *walk; DbFilterAppend *request; g_assert(obj); db_filter_applied_addrequest(obj,requestlist); origrow = obj->row; if (obj->id == NULL) { warningmsg("no id is set for obj->id"); return -1; } obj->currentcache = NULL; requestlist = g_list_first(requestlist); for (i = 0; i < obj->num; i++) { /* debugmsg("Pos %d of %d",i,obj->num); */ obj->filtered = FALSE; if (db_moveto(obj, i) < 0) { warningmsg("Unable to move to record pos %d in %s. Error %d", i, obj->name, db_moveto(obj, i)); return -2; } obj->filtered = TRUE; for (walk = requestlist; walk != NULL; walk = walk->next) { request = walk->data; if (request->fieldpos == -1) request->fieldpos = db_field_getpos(obj, request->fieldname, request->tablename); if (db_getvalue(obj, request->fieldname, request->tablename, &value) != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -