/* * Store name of table that will be used by * subsequent database functions */ int use_table(db_con_t* _h, const char* _t) { if(CON_TABLE(_h)) aug_free((char*)CON_TABLE(_h)); CON_TABLE(_h) = aug_strdup((char *) _t, _h); return 0; }
db_con_t *db_init(const char* _sqlurl) { db_con_t* res; void* t; DLOG("db_init", "entry"); /* ** this is the root memory for this database connection. */ res = aug_alloc(sizeof(db_con_t), 0); memset(res, 0, sizeof(db_con_t)); t = aug_alloc(sizeof(struct con_postgres), (char*)res); res->tail = (unsigned long) t; memset((struct con_postgres*)res->tail, 0, sizeof(struct con_postgres)); if (connect_db(res, _sqlurl) < 0) { PLOG("db_init", "Error while trying to open database, FATAL\n"); aug_free(res); return((db_con_t *) 0); } return res; }
void db_close(db_con_t* _h) { DLOG("db_close", "entry"); if(! _h) { PLOG("db_close", "no handle passed, ignored"); return; } disconnect_db(_h); aug_free(_h); }
static int disconnect_db(db_con_t* _h) { if(! _h) { DLOG("disconnect_db", "null db_con_t, ignored!\n"); return(0); } /* ** free lingering memory tree if it exists */ if(CON_SQLURL(_h)) { aug_free(CON_SQLURL(_h)); CON_SQLURL(_h) = (char *) 0; } /* ** ignore if there is no current connection */ if(CON_CONNECTED(_h) != 1) { DLOG("disconnect_db", "not connected, ignored!\n"); return 0; } /* ** make sure we are trying to close a connection that was opened ** by our process ID */ if(CON_PID(_h) == getpid()) { PQfinish(CON_CONNECTION(_h)); CON_CONNECTED(_h) = 0; } else { DLOG("disconnect_db", "attempt to release connection not owned, ignored!\n"); } return 0; }
static int connect_db(db_con_t* _h, const char* _db_url) { char* user, *password, *host, *port, *database; if(! _h) { PLOG("connect_db", "must pass db_con_t!"); return(-1); } if(CON_CONNECTED(_h)) { DLOG("connect_db", "disconnect first!"); disconnect_db(_h); } /* ** CON_CONNECTED(_h) is now 0, set by disconnect_db() */ /* ** Note : ** Make a scratch pad copy of given SQL URL. ** all memory allocated to this connection is rooted ** from this. ** This is an important concept. ** as long as you always allocate memory using the function: ** mem = aug_alloc(size, CON_SQLURL(_h)) or ** str = aug_strdup(string, CON_SQLURL(_h)) ** where size is the amount of memory, then in the future ** when CON_SQLURL(_h) is freed (in the function disconnect_db()) ** all other memory allocated in this manner is freed. ** this will keep memory leaks from happening. */ CON_SQLURL(_h) = aug_strdup((char *) _db_url, (char *) _h); /* ** get the connection parameters parsed from the db_url string ** it looks like: postgres://username:userpass@dbhost:dbport/dbname ** username/userpass : name and password for the database ** dbhost : the host name or ip address hosting the database ** dbport : the port to connect to database on ** dbname : the name of the database */ if(parse_sql_url(CON_SQLURL(_h), &user,&password,&host,&port,&database) < 0) { char buf[256]; sprintf(buf, "Error while parsing %s", _db_url); PLOG("connect_db", buf); aug_free(CON_SQLURL(_h)); return -3; } /* ** finally, actually connect to the database */ CON_CONNECTION(_h) = PQsetdbLogin(host,port,NULL,NULL,database,user, password); if(CON_CONNECTION(_h) == 0 || PQstatus(CON_CONNECTION(_h)) != CONNECTION_OK) { PLOG("connect_db", PQerrorMessage(CON_CONNECTION(_h))); PQfinish(CON_CONNECTION(_h)); aug_free(CON_SQLURL(_h)); return -4; } CON_PID(_h) = getpid(); /* ** all is well, database was connected, we can now submit_query's */ CON_CONNECTED(_h) = 1; return 0; }