📄 history.c
字号:
/**************************************************************** * * * Copyright (c) 2001-2007 McObject LLC. All Right Reserved. * * * ****************************************************************//* * This sample demostrates eXtremeDB history interfaces. * Object history is created when an object that belongs * to the class declared with the history attribute is * updated. The number of versions is decalred in the * schema, and runtime maintains the history depth * * This sample code first populates a number of objects, * creates a random number of versions for each object, * reads and displays the history for each object, and * finally deletes all the objects along with their versions. * Statistics is collected and displayed before and after * history is created. */#include <platform.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "histdb.h"static const char *dbname = "HistDb";static const int SEGSZ = 1024 * 32000UL;#ifndef MCO_PLATFORM_X64static const int PAGESIZE = 96;#elsestatic const int PAGESIZE = 192;#endifconst int MAP_ADDRESS = 0x20000000;/* define this to test history with BLOBs */#define WITH_BLOBS#define WITH_UPDATES#define NUMOBJECTS 500void _SH_(void) { char text[] = { "\nThis sample code first populates a database,\n" "creates a random number of versions for each object,\n" "reads and displays the history for each object, and\n" "finally, deletes all the objects along with their versions.\n" "Class statistics is collected and displayed before and after\n" "history is created.\n" }; char text1[] = { "Copyright (c) 2001-2007 McObject LLC. All Right Reserved.\n\n" }; printf("%s\neXtremeDB runtime version %d.%d, build %d\n%s\n\nPress Enter to start", text, MCO_COMP_VER_MAJOR, MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM,text1); getchar();}static int random_string(int len, char * str) { int ind; for (ind = 0; ind < len; ind++) { int num = 'A' + rand()%('Z'-'A'); str[ind]= (char)num; } return 0;}static uint2 rand2( uint2 lowlimit, uint2 uplimit ) { int n = rand(); return( n % (uplimit - lowlimit + 1) ) + lowlimit;}void showStat( mco_db_h db, uint2 class_code ) { MCO_RET rc = 0; mco_trans_h t; mco_class_stat_t stat; mco_trans_start( db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t ); rc = mco_class_stat_get( t, class_code, &stat ); mco_trans_commit( t ); if ( rc == MCO_S_OK ) { printf( "\n\tStatistics for the class with code %d:\n" "\tNumber of objects:\t%ld\n" "\tTotal core pages used:\t%ld\n" "\tTotal blob pages used:\t%ld\n" "\tTotal core space used:\t%ld\n", class_code, stat.objects_num, stat.core_pages, stat.blob_pages, stat.core_space ); }}/* fatal error handler */static void errhandler( int n ) { printf( "\neXtremeDB runtime fatal error: %d", n ); getchar(); exit( -1 );}static int erase(mco_db_h db, int num) { int8 u8; MCO_RET rc; mco_trans_h t; Hist hist;#ifdef MCO_CFG_QUAD_STRUCT u8.lo = num; u8.hi = 0;#else /* MCO_CFG_QUAD_STRUCT */ u8 = num;#endif /* MCO_CFG_QUAD_STRUCT */ rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); if(rc) return rc; rc = Hist_autoid_find (t, u8, &hist); if (rc) { mco_trans_rollback(t); return rc; }#ifdef MCO_CFG_QUAD_STRUCT printf ("erasing object with autoid = (%ld, %ld)......... ",u8.lo, u8.hi);#else /* MCO_CFG_QUAD_STRUCT */ printf ("erasing object with autoid = (%lld)......... ",u8);#endif /* MCO_CFG_QUAD_STRUCT */ rc|= Hist_delete ( &hist ); if (rc) { mco_trans_rollback(t); printf("failed\n"); } else { rc = mco_trans_commit(t); if (rc) printf("failed\n"); else printf("successful\n"); } return rc;}static int scan(mco_db_h db, int num) { int8 u8; uint2 u2;#ifdef WITH_BLOBS uint4 blob_size; char *blob;#endif MCO_RET rc; mco_trans_h t; Hist hist, hhist1;;#ifdef MCO_CFG_QUAD_STRUCT u8.lo = num; u8.hi = 0;#else /* MCO_CFG_QUAD_STRUCT */ u8 = num;#endif /* MCO_CFG_QUAD_STRUCT */ rc = mco_trans_start(db,MCO_READ_ONLY,MCO_TRANS_FOREGROUND,&t); if(rc) return rc; rc = Hist_autoid_find (t, u8, &hist); if (rc) { mco_trans_rollback(t); return rc; } Hist_u2_get (&hist, &u2);#ifdef MCO_CFG_QUAD_STRUCT printf("object_id (%ld,%ld) history: ", u8.lo, u8.hi);#else /* MCO_CFG_QUAD_STRUCT */ printf("object_id (%lld) history: ", u8 );#endif /* MCO_CFG_QUAD_STRUCT */ while(1) { printf("%d ", u2); if (MCO_S_OK != (rc = Hist_version_prev(&hist, &hhist1))) break; hist = hhist1; Hist_u2_get (&hist, &u2);#ifdef WITH_BLOBS Hist_blo_size(&hist, &blob_size); if (!(blob = malloc(blob_size))) break; Hist_blo_get(&hist, 0, blob, blob_size, NULL); free(blob);#endif } rc = mco_trans_commit(t); if (rc) printf("error %d\n", rc); else printf("\n"); return rc;}static int insert(mco_db_h db, int num) { MCO_RET rc; mco_trans_h t; Hist hist_obj;#ifdef WITH_BLOBS uint4 blob_size; char *blob = 0;#endif rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); if(rc) return rc; rc = Hist_new(t, &hist_obj); if (rc) { printf("rc=%d\n", rc); goto err; } rc = Hist_u2_put(&hist_obj,(uint2)num); if (rc) goto err;#ifdef WITH_BLOBS /* add blob */ blob_size = rand2(1000, 8000); //blob_size = 320; if(!(blob = malloc(blob_size))) goto err; random_string(blob_size, blob); rc = Hist_blo_put (&hist_obj, blob, blob_size ); free(blob); if (rc) goto err; // Hist_autoid_get( &hist_obj, &u8);#endif rc = mco_trans_commit(t); return rc;err: mco_trans_rollback(t); return rc;}static int update(mco_db_h db, int num) { int8 u8; uint2 u2; int i, num_revs;#ifdef WITH_BLOBS uint4 blob_size; char *blob;#endif MCO_RET rc; mco_trans_h t; Hist hist;#ifdef MCO_CFG_QUAD_STRUCT u8.lo = num; u8.hi = 0;#else /* MCO_CFG_QUAD_STRUCT */ u8 = num;#endif /* MCO_CFG_QUAD_STRUCT */ num_revs = rand2(1, Hist_versions_limit<<1); for (i=0; i< num_revs; i++) { rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t); if(rc) { goto err; } rc = Hist_autoid_find (t, u8, &hist); if (rc ) goto err; /* Create history for the object; We are going to make updates, thus makeing object revisions - only a number of revisions specified in the schema is kept */ Hist_u2_get (&hist, &u2); Hist_u2_put (&hist, ++u2); /* update blob field too */#ifdef WITH_BLOBS Hist_blo_size (&hist, &blob_size); if (!(blob = malloc(blob_size))) goto err; Hist_blo_get (&hist, 0, blob, blob_size, NULL); blob[0]='Z' + i; Hist_blo_put(&hist, blob, blob_size ); free(blob);#endif rc =mco_trans_commit(t); } return 0;err: mco_trans_rollback(t); return rc;}int main( void ) { MCO_RET rc; mco_db_h db = 0; int num = NUMOBJECTS; char * start_mem; mco_runtime_info_t info; _SH_(); mco_get_runtime_info( &info); if ( !info.mco_versioning_supported ) { printf("\nHistory feature is not available without \"versioning\" support or for the HA-enabled database runtime\n"); printf("\nPress Enter key to exit" ); getchar(); PROG_EXIT(1); }; if ( info.mco_shm_supported ) { start_mem = (char*)MAP_ADDRESS; } else { start_mem = (char*)malloc(SEGSZ); if (!start_mem) { printf("Couldn't allocated memory\n"); exit (1); } }; /* set fatal error handler */ mco_error_set_handler( &errhandler ); rc = mco_runtime_start(); rc = mco_db_open( dbname, histdb_get_dictionary(), start_mem, SEGSZ, (uint2) PAGESIZE ); if ( rc ) { printf( "\nerror creating database" ); if ( !info.mco_shm_supported ) free( start_mem ); exit( 1 ); } /* connect to the database, obtain a database handle */ mco_db_connect( dbname, &db ); printf( "\nDatabase created successfully, db handle = %d\n%dK allocated for the database\nDatabase pagesize is %d bytes\n\n", db, SEGSZ/1024, PAGESIZE ); printf("Database statistics before the initial insert:\n"); showStat( db, Hist_code); while ( 0 < num-- ) { /* create a new object */ rc = insert(db, num); if (rc != 0) break; } printf("\nDatabase statistics after the initial insert:\n"); showStat( db, Hist_code);#ifdef WITH_UPDATES num = NUMOBJECTS; for (num=1; num < NUMOBJECTS+1; num++) update(db, num); printf("\nDatabase statistics after the update:\n"); showStat( db, Hist_code);#endif printf("\nReading objects history:\n"); num = NUMOBJECTS; for (num=1; num < NUMOBJECTS+1; num++) scan(db, num); printf("\nErasing objects:\n"); num = NUMOBJECTS; for (num=1; num < NUMOBJECTS+1; num++) erase(db, num); showStat( db, Hist_code); /* disconnect from the database, db is no longer valid */ mco_db_disconnect( db ); /* destroy the db */ mco_db_close( dbname ); mco_runtime_stop(); if ( !info.mco_shm_supported ) free( start_mem ); printf("\nPress Enter key to exit" ); getchar(); PROG_EXIT(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -