Changeset 285:0daf6fc2b751 in freeDiameter for extensions/app_acct/acct_db.c
- Timestamp:
- Apr 30, 2010, 5:55:16 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/app_acct/acct_db.c
r284 r285 51 51 52 52 static const char * stmt = "acct_db_stmt"; 53 static PGconn *conn = NULL; 54 53 #ifndef TEST_DEBUG 54 static 55 #endif /* TEST_DEBUG */ 56 PGconn *conn = NULL; 57 58 /* Initialize the database context: connection to the DB, prepared statement to insert new records */ 55 59 int acct_db_init(void) 56 60 { … … 63 67 int idx = 0; 64 68 PGresult * res; 65 #define REALLOC_SIZE 1024 69 #define REALLOC_SIZE 1024 /* We extend the buffer by this amount */ 66 70 67 71 TRACE_ENTRY(); … … 76 80 acct_db_free(); 77 81 return EINVAL; 78 } else { 79 TRACE_DEBUG(INFO, "Connection to database successfull: user:%s, db:%s, host:%s.", PQuser(conn), PQdb(conn), PQhost(conn)); 80 } 82 } 83 if (PQprotocolVersion(conn) < 3) { 84 fd_log_debug("Database protocol version is too old, version 3 is required for prepared statements.\n"); 85 acct_db_free(); 86 return EINVAL; 87 } 88 89 TRACE_DEBUG(FULL, "Connection to database successful, server version %d.", PQserverVersion(conn)); 81 90 82 91 /* Now, prepare the request object */ … … 174 183 PQclear(res); 175 184 176 177 185 free(sql); 186 acct_rec_empty(&emptyrecords); 187 188 /* Ok, ready */ 178 189 return 0; 179 190 } 180 191 192 /* Terminate the connection to the DB */ 181 193 void acct_db_free(void) 182 { 183 if (conn) 194 { 195 if (conn) { 196 /* Note: the prepared statement is automatically freed when the session terminates */ 184 197 PQfinish(conn); 185 conn = NULL; 198 conn = NULL; 199 } 186 200 } 187 201 202 /* When a new message has been received, insert the content of the parsed mapping into the DB (using prepared statement) */ 188 203 int acct_db_insert(struct acct_record_list * records) 189 204 { 190 return ENOTSUP; 205 char **val; 206 int *val_len; 207 int *val_isbin; 208 int idx = 0; 209 PGresult *res; 210 struct fd_list *li; 211 212 TRACE_ENTRY("%p", records); 213 CHECK_PARAMS( conn && records ); 214 215 /* First, check if the connection with the DB has not staled, and eventually try to fix it */ 216 if (PQstatus(conn) != CONNECTION_OK) { 217 /* Attempt a reset */ 218 PQreset(conn); 219 if (PQstatus(conn) != CONNECTION_OK) { 220 TRACE_DEBUG(INFO, "Lost connection to the database server, and attempt to reestablish it failed"); 221 TODO("Terminate the freeDiameter instance completly?"); 222 return ENOTCONN; 223 } 224 } 225 226 /* Alloc the arrays of parameters */ 227 CHECK_MALLOC( val = calloc(records->nball, sizeof(const char *)) ); 228 CHECK_MALLOC( val_len = calloc(records->nball, sizeof(const int)) ); 229 CHECK_MALLOC( val_isbin = calloc(records->nball, sizeof(const int)) ); 230 231 /* Now write all the map'd records in these arrays */ 232 for (li = records->all.next; li != &records->all; li = li->next) { 233 struct acct_record_item * r = (struct acct_record_item *)(li->o); 234 if (r->value) { 235 val_isbin[idx] = 1; /* We always pass binary parameters */ 236 switch (r->param->avptype) { 237 case AVP_TYPE_OCTETSTRING: 238 val[idx] = (void *)(r->value->os.data); 239 val_len[idx] = r->value->os.len; 240 break; 241 242 case AVP_TYPE_INTEGER32: 243 case AVP_TYPE_UNSIGNED32: 244 case AVP_TYPE_FLOAT32: 245 r->scalar.v32 = htonl(r->value->u32); 246 val[idx] = &r->scalar.c; 247 val_len[idx] = sizeof(uint32_t); 248 break; 249 250 case AVP_TYPE_INTEGER64: 251 case AVP_TYPE_UNSIGNED64: 252 case AVP_TYPE_FLOAT64: 253 r->scalar.v64 = htonll(r->value->u64); 254 val[idx] = &r->scalar.c; 255 val_len[idx] = sizeof(uint64_t); 256 break; 257 258 default: 259 ASSERT(0); /* detect bugs */ 260 } 261 } 262 263 idx++; 264 } 265 266 /* OK, now execute the SQL statement */ 267 res = PQexecPrepared(conn, stmt, records->nball, (const char * const *)val, val_len, val_isbin, 1 /* We actually don't care here */); 268 269 /* Done with the parameters */ 270 free(val); 271 free(val_len); 272 free(val_isbin); 273 274 /* Now check the result code */ 275 if (PQresultStatus(res) != PGRES_COMMAND_OK) { 276 TRACE_DEBUG(INFO, "An error occurred while INSERTing in the database: %s", PQerrorMessage(conn)); 277 PQclear(res); 278 return EINVAL; /* It was probably a mistake in configuration file... */ 279 } 280 PQclear(res); 281 282 /* Ok, we are done */ 283 return 0; 191 284 } 192 285
Note: See TracChangeset
for help on using the changeset viewer.