📄 dbfield.c
字号:
#include <glib.h>#include <string.h>#include "dbwrapper.h"#include "dbfield.h"#include "dbobject.h"#include "debug.h"#include "dbobjectvalid.h"#include "dbsqlparse.h"#include "dbsuggest.h"/** * db_field_getpos: * @obj: Database Object * @fieldname: Field to look up * * Find out where a field * * Returns: negitive on failure, else the index position. */gintdb_field_getpos(Object * obj, gchar * fieldname, gchar * tablename) { gint retval = 0; DbField *f; f = db_field_dbfind(obj, fieldname, tablename); if (f == NULL) return -1; else return f->fieldposinsql; return retval; }/** * db_field_read: * @obj: Database Object * @fieldname: Field to look up * @retval: Where to store the record after reading * * Will read current recordset based on your currently selected row in the object to get the value * asked for in the @fieldname. * * Returns: non-zero on failure */gintdb_field_read(Object * obj, gchar * fieldname, gchar * tablename, char **retval) { gint pos; g_assert(obj); g_assert(fieldname); *retval = NULL; pos = db_field_getpos(obj, fieldname, tablename); if (pos < 0 || pos > obj->numfield) { warningmsg("Unable to find field %s in %s. \nSql : %s", fieldname, obj->name, obj->query); return -1; } if (obj->res == NULL) { warningmsg("RecordSet is NULL. I can not read field %s from %s", fieldname, obj->name); g_assert(NULL); return -2; } *retval = db_dbgetvalue(obj->res, obj->row, pos); if (*retval != NULL) g_strstrip(*retval); /* m.essage("%s read from %s.%s",*retval,tablename,fieldname); */ return 0; }/** * db_field_getname: * @obj: Database object * @fieldpos: Field position. * @fieldstr: Return string for fieldname * @tablestr: Return string for tablename * * Get details about a record at the field position. * * Returns: non-zero on failure */gintdb_field_get(Object * obj, gint fieldpos, gchar ** fieldstr, gchar ** tablestr) { *fieldstr = NULL; *tablestr = NULL; g_assert(obj); g_assert(fieldpos >= 0); g_assert(fieldpos < obj->numfield); *fieldstr = obj->field[fieldpos]->field; *tablestr = obj->field[fieldpos]->table; return 0; }/** * db_field_arraypos: * @field: Array of DbField, in which to search for fieldname * @num: number of elements in @field * @fieldname: Field to search for. * * * Returns: Negitive on error else position in array */gintdb_field_arraypos(DbField ** field, gint num, gchar * fieldname) { gint i; for (i = 0; i < num; i++) { if (strcmp(field[i]->field, fieldname) == 0) return i; } return -1; }/** * db_field_getbytable: * * Should really be in dbgather, but its here anyway. Return a DbField based on @pos. * this is just another one of those nice functions. * * Returns: %NULL on error else a newly created DbField *//* note to coder: dbgather has all that you need */DbField *db_field_getbytable(gchar * tablename, gint pos) { DbField *field; DbTableDef *tabledef; DbFieldDef *fielddef; g_assert(tablename); tabledef = db_findtable(tablename); if (tabledef == NULL) { errormsg("Unable to find %s in database", tablename); return NULL; } if (pos >= tabledef->num || pos < 0) { errormsg("invalid pos of %d specified in %s", pos, tablename); return NULL; } if (tabledef->field[pos] == NULL) { errormsg("Unable to find a field at pos %d in table %s", pos, tablename); return NULL; } fielddef = tabledef->field[pos]; /* create the field object now */ field = (DbField *) mem_alloc(sizeof(DbField)); field->fielddef = fielddef; field->tabledef = tabledef; field->path = NULL; field->fieldposinsql = pos; field->field = mem_strdup(fielddef->name); field->table = mem_strdup(tabledef->name); /* debugmsg("Field %s, field %s",field->fielddef->name,field->field); */ return field; }/** * db_field_numfieldbytable: * * Gets the number fields in a object. * * Returns: Number of fields in the table, else negitive on failure *//* Note: same as above function */gintdb_field_numfieldbytable(gchar * tablename) { DbTableDef *tabledef; g_assert(tablename); tabledef = db_findtable(tablename); if (tabledef == NULL) { errormsg("Unable to find %s in database", tablename); return -1; } return tabledef->num; }static gint db_field_populate_singletable(Object * obj);/** * db_field_populate: * @obj: database object * * Fill in all the information about that object which it doens't already know. DbField, number * of fields, what tables fields are from, and the name of table are added. It hopes * that there is a recordset present * * Returns: non-zero on failure */gintdb_field_populate(Object * obj) { GList *walk, *reqfields, *fieldlist; g_assert(obj); db_field_freeall(obj); /* If there is no record set on this object then just guess, and if you cant guess give up */ if (db_isrecordset(obj) == FALSE) return db_field_populate_singletable(obj); if (obj->name != NULL) mem_free(obj->name); /* build up list of fields in the sql statement */ reqfields = db_sqlparse_getselectfields(obj->query); /* error checking */ if (obj->res->basetable == NULL) { errormsg("Basetable is NULL, this not good. This is a real nasty SQL statement"); return -1; } /* set the name on the table */ obj->name = mem_strdup(obj->res->basetable); /* m.essage("populating %s",obj->name); */ /* For each item in the sql statement get fields */ if (reqfields == NULL) { debugmsg("No fields present to read from, will assume all fields in %s.",obj->name); reqfields = db_field_allfieldsinresult(obj); } walk = g_list_first(reqfields); while (walk != NULL) { fieldlist = db_field_populate_element(walk->data, obj->name); db_field_addfieldlist(obj, fieldlist); g_list_free(fieldlist); walk = walk->next; } db_sqlparse_freeselectfields(reqfields); return 0; }/** * db_field_allfieldsinresult: * @obj: Database object which has a already excuted SQL statement. * * Given an SQL statement this returns a GList* of all the returned fields * in the sql statement. Use db_sqlparse_freeselectfields(); to free the results * of this function. * * Returns: GList* of items, use g_list_free on it when done. */GList *db_field_allfieldsinresult(Object *obj) { gchar *fieldname; gint numfield, i; GList *retlist = NULL; g_assert(obj); numfield = db_dbnumfields(obj->res); for (i=0;i<numfield;i++) { fieldname = db_dbfieldname(obj->res, i); retlist = g_list_prepend(retlist,strdup(fieldname)); } return retlist; }/** * db_field_populate_singletable: * * Go to dbgather and use the information in obj->name to get the numfields and fill in each * dbfield for that single field. Uses db_field_getbytable(). * */static gintdb_field_populate_singletable(Object * obj) { DbField *f; GList *retlist = NULL; gint i, num; if (obj->name == NULL) { errormsg("Empty object. hmm. i know nothing. Please assign a name to this object prior."); return -1; } num = db_field_numfieldbytable(obj->name); for (i = 0; i < num; i++) { f = db_field_getbytable(obj->name, i); retlist = g_list_append(retlist, f); } /* put items into the object */ db_field_addfieldlist(obj, retlist); /* free up */ g_list_free(retlist); return 0; }/** * db_field_populate_element: * @inputfield: the field specificed in a sql statement after a select * @deftable: default table to use, this is obj->name * * For every item in the select statement go though and work out what fields are need and * create a db. * * Returns: GList of DbField's */GList *db_field_populate_element(gchar * inputfield, gchar * deftable) { gchar *tablename, *fieldname; GList *retlist = NULL; gint wildcard, num, i; DbField *f; wildcard = db_suggest_wildcard(inputfield, &fieldname, &tablename); if (wildcard < 0) { errormsg("Error occured in parsing %s", inputfield); return NULL; } if (tablename == NULL) tablename = mem_strdup(deftable); /* No wildcard, just a straight table.fieldname property. hmm */ if (wildcard == 0 && fieldname != NULL) { f = db_field_getbyfield(fieldname, tablename); retlist = g_list_append(retlist, f); } /* you specified table.* or * */ if (wildcard == 1) { /* table.* thingy */ num = db_field_numfieldbytable(tablename); for (i = 0; i < num; i++) { f = db_field_getbytable(tablename, i); g_assert(f); retlist = g_list_append(retlist, f); } } /* free that unneeded stuff */ if (tablename != NULL) ; mem_free(tablename); if (fieldname != NULL) mem_free(fieldname); return retlist; }/** * db_field_getbyfield: * @fieldname: The fieldname we are looking for * @tablename: The table to look for the field in * * Create a DbField for @fieldname in table @tablename. * * Returns: created DbField object */DbField *db_field_getbyfield(gchar * fieldname, gchar * tablename) { DbField *field; gint i; g_assert(tablename); field = (DbField *) mem_alloc(sizeof(DbField)); memset(field, 0, sizeof(DbField)); field->tabledef = db_findtable(tablename); if (field->tabledef == NULL) { errormsg("Unable to find %s.%s in database", tablename, fieldname); mem_free(field); return NULL; } for (i = 0; i < field->tabledef->num; i++) { if (strcmp(fieldname, field->tabledef->field[i]->name) == 0) { field->fielddef = field->tabledef->field[i]; field->fieldposinsql = i; } } field->path = NULL; field->field = mem_strdup(fieldname); field->table = mem_strdup(tablename); return field; }static voiddb_field_expandfieldlist(Object * obj, DbField * f) { /* woow look at that saved resources now */ if (obj->numfield % 20 == 0 || obj->numfield == 0) obj->field = (DbField **) mem_realloc(obj->field, sizeof(DbField *) * (obj->numfield + 21)); f->fieldposinsql = obj->numfield; obj->field[obj->numfield] = f; obj->numfield++; }/** * db_field_addfieldlist: * * Given a @fieldlist of DbField's, add them into the object and increase the number of fields * accordingly. If a result exists verify that these fields actually do exist in the query. */gintdb_field_addfieldlist(Object * obj, GList * fieldlist) { DbField *f; GList *walk; g_assert(obj); for (walk = g_list_first(fieldlist); walk != NULL; walk = walk->next) { f = walk->data; if (f == NULL) continue; /* check to see if data is acutally in the record set */ /* (db_field_checkinresult(obj->res,f)!= 0) { errormsg("Unable to find %s in the record set",f->fieldname); continue; } */ if (db_field_dbfind(obj, f->field, f->table) == NULL) db_field_expandfieldlist(obj, f); } return 0; }/** * db_field_free: * @field: Field to be freed * * Free up a dbfield block */voiddb_field_free(DbField * field) { if (field->field != NULL) mem_free(field->field); if (field->table != NULL) mem_free(field->table); if (field->path != NULL) { g_list_free(field->path->tablepath); mem_free(field->path->field); mem_free(field->path->finaltable); mem_free(field->path); } mem_free(field); }/** * db_field_freeall: * * Free all the field values in @obj. */voiddb_field_freeall(Object * obj) { gint i; g_assert(obj); if (obj->field == NULL) return ; for (i = 0; i < obj->numfield; i++) db_field_free(obj->field[i]); mem_free(obj->field); obj->field = NULL; obj->numfield = 0; }/** * db_field_test * @obj: database object with field information already set * * Go though the field information in @obj and work out the fieldpos for each item in the record set, * well atleast verify that this stuff is right you know. * * Returns: non-zero on error */gintdb_field_test(Object * obj) { gint i, retval = 0; gchar *tmpstr; if (db_isrecordset(obj) == FALSE) return -1; for (i = 0; i < obj->numfield; i++) { tmpstr = db_dbfieldname(obj->res, i); if (strcmp(tmpstr, obj->field[i]->field) != 0) { errormsg("what i think is in record set and what is, is differnet. %s != %s", tmpstr, obj->field[i]->field); retval++; } } return retval; }/** * db_field_find: * @obj: database object * @fieldname: fieldname to search for * @tablename: table where it resides, or %NULL for default table. * * Find @fieldname in the field list in the object, else * returns %NULL if it can't find it. If you pass in %NULL * for the tablename it will first of all look for that field in * your base table (obj->name) and if that fails it will look * for any general match which it will return. * * Returns: %NULL if you can't find it else the DbField in * object. Do not free this variable */DbField *db_field_dbfind(Object * obj, gchar * fieldname, gchar * tablename) { gint i; g_assert(obj); if (tablename == NULL) tablename = obj->name; if (tablename == NULL) { for (i = 0; i < obj->numfield; i++) if (strcmp(fieldname, obj->field[i]->field) == 0) return obj->field[i]; return NULL; } for (i = 0; i < obj->numfield; i++) if (strcmp(fieldname, obj->field[i]->field) == 0 && strcmp(tablename, obj->field[i]->table) == 0) return obj->field[i]; return NULL; }DbField *db_field_copy(DbField * srcfield) { DbField *field = NULL; g_assert(srcfield); field = mem_alloc(sizeof(DbField)); memcpy(field, srcfield, sizeof(DbField)); field->field = mem_strdup(srcfield->field); field->table = mem_strdup(srcfield->table); return field; }#ifdef _PORTED/* This is the older code that i need to salavage some of the bits of for cooler stuff */gint fieldpos, i, nfields;gchar *suggestfield;g_assert(obj);g_assert(field);fieldpos = db_getfieldposintable(obj->table, field);if (db_isfieldposok(obj, fieldpos) == TRUE) { if (db_isrecordset(obj) == TRUE && strcmp(db_dbfieldname(obj->res, fieldpos), obj->table->field[fieldpos]->name) != 0) { fieldpos = -1; debugmsg("having problems finding field name here"); } }else fieldpos = -1;/* if (fieldpos != -1) { if (fieldpos < 0 || fieldpos >= obj->table->num) { warningmsg("referecing outside of fieldname boundaries"); fieldpos = -1; } else if (db_isrecordset(obj)==TRUE && strcmp(db_dbfieldname(obj->res, fieldpos), obj->table->field[fieldpos]->name) != 0) { fieldpos = -1; debugmsg("having problems finding field name here"); } } *//* failed to find a field pos so try a different way to search */if (fieldpos == -1) { g_assert(obj->res); nfields = db_dbnumfields(obj->res); for (i = 0; i < nfields; i++) if (strcmp(db_dbfieldname(obj->res, i), field) == 0) { fieldpos = i; break; } }/* try even harder again */if (fieldpos == -1) if ((suggestfield = db_sqlparse_suggestfield(field)) != NULL) { fieldpos = db_getfieldposintable(obj->table, suggestfield); mem_free(suggestfield); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -