int sprint_record(void *db, wg_int *rec, char **buf, int *bufsize, char **bptr, int format, int showid, int depth, int maxdepth, int strenc) { int i,limit; wg_int enc, len; #ifdef USE_CHILD_DB void *parent; #endif limit=MIN_STRLEN; str_guarantee_space(buf, bufsize, bptr, MIN_STRLEN); if (rec==NULL) { snprintf(*bptr, limit, JS_NULL); (*bptr)+=strlen(JS_NULL); return 1; } if (format!=0) { // json **bptr= '['; (*bptr)++; } #ifdef USE_CHILD_DB parent = wg_get_rec_owner(db, rec); #endif if (1) { len = wg_get_record_len(db, rec); if (showid) { // add record id (offset) as the first extra elem of record snprintf(*bptr, limit-1, "%d",wg_encode_record(db,rec)); *bptr=*bptr+strlen(*bptr); } for(i=0; i<len; i++) { enc = wg_get_field(db, rec, i); #ifdef USE_CHILD_DB if(parent != db) enc = wg_translate_hdroffset(db, parent, enc); #endif str_guarantee_space(buf, bufsize, bptr, MIN_STRLEN); if (i || showid) { if (format!=0) **bptr = ','; else **bptr = CSV_SEPARATOR; (*bptr)++; } *bptr=sprint_value(db, enc, buf, bufsize, bptr, format, showid, depth, maxdepth, strenc); } } if (format!=0) { // json str_guarantee_space(buf, bufsize, bptr, MIN_STRLEN); **bptr = ']'; (*bptr)++; } return 1; }
void run_demo(void* db) { void *rec = NULL, *firstrec = NULL, *nextrec = NULL; /* Pointers to a database record */ wg_int enc; /* Encoded data */ wg_int lock_id; /* Id of an acquired lock (for releasing it later) */ wg_int len; int i; int intdata, datedata, timedata; char strbuf[80]; printf("********* Starting demo ************\n"); /* Begin by creating a simple record of 3 fields and fill it * with integer data. */ printf("Creating first record.\n"); rec=wg_create_record(db, 3); if (rec==NULL) { printf("rec creation error.\n"); return; } /* Encode a field, checking for errors */ enc = wg_encode_int(db, 44); if(enc==WG_ILLEGAL) { printf("failed to encode an integer.\n"); return; } /* Negative return value shows that an error occurred */ if(wg_set_field(db, rec, 0, enc) < 0) { printf("failed to store a field.\n"); return; } /* Skip error checking for the sake of brevity for the rest of fields */ enc = wg_encode_int(db, -199999); wg_set_field(db, rec, 1, enc); wg_set_field(db, rec, 2, wg_encode_int(db, 0)); /* Now examine the record we have created. Get record length, * encoded value of each field, data type and decoded value. */ /* Negative return value shows an error. */ len = wg_get_record_len(db, rec); if(len < 0) { printf("failed to get record length.\n"); return; } printf("Size of created record at %p was: %d\n", rec, (int) len); for(i=0; i<len; i++) { printf("Reading field %d:", i); enc = wg_get_field(db, rec, i); if(wg_get_encoded_type(db, enc) != WG_INTTYPE) { printf("data was of unexpected type.\n"); return; } intdata = wg_decode_int(db, enc); /* No error checking here. All integers are valid. */ printf(" %d\n", intdata); } /* Fields can be erased by setting their value to 0 which always stands for NULL value. */ printf("Clearing field 1.\n"); wg_set_field(db, rec, 1, 0); if(wg_get_field(db, rec, 1)==0) { printf("Re-reading field 1 returned a 0 (NULL) field.\n"); } else { printf("unexpected value \n"); return; } /* Fields can be updated with data of any type (the type is not fixed). */ printf("Updating field 0 to a floating-point number.\n"); enc = wg_encode_double(db, 56.9988); wg_set_field(db, rec, 0, enc); enc = wg_get_field(db, rec, 0); if(wg_get_encoded_type(db, enc) == WG_DOUBLETYPE) { printf("Re-reading field 0 returned %f.\n", wg_decode_double(db, enc)); } else { printf("data was of unexpected type.\n"); return; } /* Create a next record. Let's assume we're in an environment where * the database is used concurrently, so there's a need to use locking. */ printf("Creating second record.\n"); /* Lock id of 0 means that the operation failed */ lock_id = wg_start_write(db); if(!lock_id) { printf("failed to acquire lock.\n"); return; } /* Do the write operation we acquired the lock for. */ rec=wg_create_record(db, 6); /* Failing to release the lock would be fatal to database operation. */ if(!wg_end_write(db, lock_id)) { printf("failed to release lock.\n"); return; } if (!rec) { printf("rec creation error.\n"); return; } /* Reading also requires locking./ */ lock_id = wg_start_read(db); if(!lock_id) { printf("failed to acquire lock.\n"); return; } /* Do our read operation... */ len = wg_get_record_len(db, rec); /* ... and unlock immediately */ if(!wg_end_read(db, lock_id)) { printf("failed to release lock.\n"); return; } if(len < 0) { printf("failed to get record length.\n"); return; } printf("Size of created record at %p was: %d\n", rec, (int) len); /* Let's find the first record in the database */ lock_id = wg_start_read(db); firstrec = wg_get_first_record(db); wg_end_read(db, lock_id); if(!firstrec) { printf("Failed to find first record.\n"); return; } printf("First record of database had address %p.\n", firstrec); /* Let's check what the next record is to demonstrate scanning records. */ nextrec = firstrec; lock_id = wg_start_read(db); do { nextrec = wg_get_next_record(db, nextrec); if(nextrec) printf("Next record had address %p.\n", nextrec); } while(nextrec); printf("Finished scanning database records.\n"); wg_end_read(db, lock_id); /* Set fields to various values. Field 0 is not touched at all (un- * initialized). Field 1 is set to point to another record. */ printf("Populating second record with data.\n"); /* Let's use the first record we found to demonstrate storing * a link to a record in a field inside another record. */ lock_id = wg_start_write(db); enc = wg_encode_record(db, firstrec); wg_set_field(db, rec, 1, enc); wg_end_write(db, lock_id); /* Now set other fields to various data types. To keep the example shorter, * the locking and unlocking operations are omitted (in real applications, * this would be incorrect usage if concurrent access is expected). */ wg_set_field(db, rec, 2, wg_encode_str(db, "This is a char array", NULL)); wg_set_field(db, rec, 3, wg_encode_char(db, 'a')); /* For time and date, we use current time in local timezone */ enc = wg_encode_date(db, wg_current_localdate(db)); if(enc==WG_ILLEGAL) { printf("failed to encode date.\n"); return; } wg_set_field(db, rec, 4, enc); enc = wg_encode_time(db, wg_current_localtime(db)); if(enc==WG_ILLEGAL) { printf("failed to encode time.\n"); return; } wg_set_field(db, rec, 5, enc); /* Now read and print all the fields. */ wg_print_record(db, (wg_int *) rec); printf("\n"); /* Date and time can be handled together as a datetime object. */ datedata = wg_decode_date(db, wg_get_field(db, rec, 4)); timedata = wg_decode_time(db, wg_get_field(db, rec, 5)); wg_strf_iso_datetime(db, datedata, timedata, strbuf); printf("Reading datetime: %s.\n", strbuf); printf("Setting date and time to 2010-03-31, 12:59\n"); /* Update date and time to arbitrary values using wg_strp_iso_date/time */ wg_set_field(db, rec, 4, wg_encode_date(db, wg_strp_iso_date(db, "2010-03-31"))); wg_set_field(db, rec, 5, wg_encode_time(db, wg_strp_iso_time(db, "12:59:00.33"))); printf("Dumping the contents of the database:\n"); wg_print_db(db); printf("********* Demo ended ************\n"); }