/* * Insert a row into specified table * h: structure representing database connection * k: key names * v: values of the keys * n: number of key=value pairs */ int flat_db_insert(const db1_con_t* h, const db_key_t* k, const db_val_t* v, const int n) { FILE* f; int i; int l; char *s, *p; if (km_local_timestamp < *km_flat_rotate) { flat_rotate_logs(); km_local_timestamp = *km_flat_rotate; } f = CON_FILE(h); if (!f) { LM_ERR("uninitialized connection\n"); return -1; } for(i = 0; i < n; i++) { switch(VAL_TYPE(v + i)) { case DB1_INT: fprintf(f, "%d", VAL_INT(v + i)); break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_DOUBLE: fprintf(f, "%f", VAL_DOUBLE(v + i)); break; case DB1_STRING: fprintf(f, "%s", VAL_STRING(v + i)); break; case DB1_STR: fprintf(f, "%.*s", VAL_STR(v + i).len, VAL_STR(v + i).s); break; case DB1_DATETIME: fprintf(f, "%u", (unsigned int)VAL_TIME(v + i)); break; case DB1_BLOB: l = VAL_BLOB(v+i).len; s = p = VAL_BLOB(v+i).s; while (l--) { if ( !(isprint((int)*s) && *s != '\\' && *s != '|')) { fprintf(f,"%.*s\\x%02X",(int)(s-p),p,(*s & 0xff)); p = s+1; } ++s; } if (p!=s) fprintf(f,"%.*s",(int)(s-p),p); break; case DB1_BITMAP: fprintf(f, "%u", VAL_BITMAP(v + i)); break; } if (i < (n - 1)) { fprintf(f, "%c", *km_flat_delimiter); } } fprintf(f, "\n"); if (flat_flush) { fflush(f); } return 0; }
/* * Insert a row into specified table * h: structure representing database connection * k: key names * v: values of the keys * n: number of key=value pairs */ int flat_db_insert(const db_con_t* h, const db_key_t* k, const db_val_t* v, const int n) { FILE* f; int i; int auxl; str aux; char * begin = flat_iov_buf.s; if (local_timestamp < *flat_rotate) { flat_rotate_logs(); local_timestamp = *flat_rotate; } if ( !h || !CON_TAIL(h) || (f=CON_FILE(h))==NULL ) { LM_ERR("uninitialized connection\n"); return -1; } if (flat_prepare_iovec(n) < 0) { LM_ERR("cannot insert row\n"); return -1; } FLAT_LOCK(f); for(i = 0; i < n; i++) { if (VAL_NULL(v + i)) { FLAT_SET_STR(i, ""); FLAT_SET_LEN(i, 0); continue; } FLAT_SET_STR(i, FLAT_BUF); switch(VAL_TYPE(v + i)) { case DB_INT: /* guess this is 20 */ FLAT_ALLOC(20); FLAT_PRINTF("%d", VAL_INT(v+i), i); break; case DB_DOUBLE: /* guess there are max 20 digits */ FLAT_ALLOC(40); FLAT_PRINTF("%f", VAL_DOUBLE(v+i), i); break; case DB_BIGINT: /* guess there are max 20 digits */ FLAT_ALLOC(40); FLAT_PRINTF("%llu", VAL_BIGINT(v+i), i); break; case DB_STRING: auxl = strlen(VAL_STRING(v + i)); FLAT_ALLOC(auxl * 4); FLAT_COPY(i, VAL_STRING(v + i), auxl); break; case DB_STR: FLAT_ALLOC(VAL_STR(v + i).len * 4); FLAT_COPY(i, VAL_STR(v + i).s, VAL_STR(v + i).len); break; case DB_DATETIME: /* guess this is 20 */ FLAT_ALLOC(20); FLAT_PRINTF("%lu", VAL_TIME(v+i), i); break; case DB_BLOB: auxl = VAL_BLOB(v+i).len; /* the maximum size is 4l - if all chars were not printable */ FLAT_ALLOC(4 * auxl); FLAT_COPY(i, VAL_BLOB(v+i).s, auxl); break; case DB_BITMAP: /* guess this is 20 */ FLAT_ALLOC(20); FLAT_PRINTF("%u", VAL_BITMAP(v+i), i); break; } } /* reorder pointers in case they were altered by (re)allocation */ if (flat_iov_buf.s != begin && flat_iov_buf.len) { FLAT_RESET(); for (i = 0; i < n; i++) { if (!VAL_NULL(v + i)) { FLAT_SET_STR(i, FLAT_BUF); FLAT_INC(FLAT_GET_LEN(i)); } } } do { auxl = writev(fileno(f), flat_iov, 2 * n); } while (auxl < 0 && errno == EINTR); if (auxl < 0) { LM_ERR("unable to write to file: %s - %d\n", strerror(errno), errno); return -1; } /* XXX does this make sense any more? */ if (flat_flush && fflush(f) < 0) { LM_ERR("cannot flush buffer: %s - %d\n", strerror(errno), errno); } FLAT_UNLOCK(f); return 0; }
/* * Insert a row into specified table * h: structure representing database connection * k: key names * v: values of the keys * n: number of key=value pairs */ int flat_db_insert(db_con_t* h, db_key_t* k, db_val_t* v, int n) { FILE* f; int i; char delims[4], *s; size_t len; f = CON_FILE(h); if (!f) { LOG(L_CRIT, "BUG: flat_db_insert: Uninitialized connection\n"); return -1; } if (local_timestamp < *flat_rotate) { flat_rotate_logs(); local_timestamp = *flat_rotate; } for(i = 0; i < n; i++) { if (!VAL_NULL(v + i)) { // TODO: how to distinguish NULL from empty switch(VAL_TYPE(v + i)) { case DB_INT: fprintf(f, "%d", VAL_INT(v + i)); break; case DB_FLOAT: fprintf(f, "%f", VAL_FLOAT(v + i)); break; case DB_DOUBLE: fprintf(f, "%f", VAL_DOUBLE(v + i)); break; case DB_STRING: { s = (char*) VAL_STRING(v + i); delims[0] = flat_delimiter[0]; delims[1] = flat_record_delimiter[0]; delims[2] = flat_escape[0]; delims[3] = '\0'; while (*s) { len = strcspn(s, delims); fprintf(f, "%.*s", (int)len, s); s+= len; if (*s) { fprintf(f, "%c%c", flat_escape[0], *s); s++; } } break; } case DB_STR: case DB_BLOB: if (VAL_TYPE(v + i) == DB_STR) { s = VAL_STR(v + i).s; len = VAL_STR(v + i).len; } else { s = VAL_BLOB(v + i).s; len = VAL_BLOB(v + i).len; } while (len > 0) { char *c; for (c = s; len > 0 && *c != flat_delimiter[0] && *c != flat_record_delimiter[0] && *c != flat_escape[0]; c++, len--); fprintf(f, "%.*s", (int)(c-s), s); s = c; if (len > 0) { fprintf(f, "%c%c", flat_escape[0], *s); s++; len--; } } break; case DB_DATETIME: fprintf(f, "%u", (unsigned int)VAL_TIME(v + i)); break; case DB_BITMAP: fprintf(f, "%u", VAL_BITMAP(v + i)); break; } } if (i < (n - 1)) { fprintf(f, "%c", flat_delimiter[0]); } } fprintf(f, "%c", flat_record_delimiter[0]); if (flat_flush) { fflush(f); } return 0; }