DBM and GDBM and cross-platform code research
Keywords:
DBM: The database of UNIX systems, uses HASH to save unstructured data. It does not support SQL.
GNU version of GDBM: DBM.
Cross-platform C language code: C language code with cross-platform characteristics.
1.
Introduction
The Unix version of the X / Open technical specification has a database. But this database does not conform to the ANSI standard SQL technical specification (not supported SQL statement). It is just a routine that stores the search data.
DBM, GDBM is suitable for storing static, indexed data structures. It is very slow when creating data items, but very fast when retrieving data items.
This article gives a brief description of DBM, GDBM, and finally gives compatible with C-code written proposals that can be compatible with DBM, GDBM.
2.
DBM
DBM uses two data files, extensions ".pag" and ".dir". However, only one of the operation return values for the database. Note: Do not use the read-write function to manipulate the data file directly, you should access the data using the DBM provided by DBM.
2.1.
data structure
Data, indexes are saved using the following structure:
Typedef struct {
CHAR * DPTR;
Int dsize;
} Datum;
The database access structure (equivalent to FILE):
Typedef struct {int Dummy [10];
2.2.
Function introduction
#include
/ * Open Database * /
DBM * dbm_open (const char * filename, / * database file name (two files, suffix different) * /
INT file_open_flags, / * is the same as the Open function, file open flag * /
Mode_t file_mode / * is the same as the Open function, file open mode * /
);
Returns the DMB type pointer when successfully, the failure returns NULL
/*Storing data*/
INT DBM_STORE (DBM * Database_Descriptor, / * Opened the structure returned by the database operation * /
Datum key, / * Keywords to retrieve data * /
Datum Content, / * Structure for Save Data * /
INT Store_Mode / * If you are dbm_insert, the operation will fail when the data exists. If DBM_REPLACE, override the existing data * /
);
If the database open mode is "dbm_insert", the data corresponding to the key is saved, then returns 1;
If other errors appear, return a negative number;
Successful operation, return 0;
/ * Retrieve data * /
DATUM DBM_FETCH (DBM * Database_DescreiPtor, / * DBM_Open data structure * /
Datum key / * Retrieves keywords * /
);
If found, the return structure DPTR and DSIZE assigns a data pointer and data size, and if not found, the DPTR assigns NULL.
The returned DATUM structure contains a pointer to the recorded data, and the data record is still in a memory area inside the DBM. If necessary, it should be copied to other variables. / * Close the database * /
Void DBM_Close (DBM * Database_Descriptor); / * DBM_Open Returned Data Structure * /
/ * Other functions * /
INT DBM_DELETE (DBM * Database_Descriptor, Datum Key); / * Delete Index as Key Data * /
Operation successfully returns 0;
INT DBM_ERROR (DBM * Database_Descriptor); / * Simple test of the database. No error returns 0. * /
No error returns 0;
DBM_FirstKey (), DBM_NEXTKEY () is generally used to retrieve all data in the database.
E.g:
For (Key = dbm_firstkey; key.dptr; key = dbm_nextkey;
3.
gdbm
GDBM uses a data file and is different from DBM. Note: Do not use the read and write function to manipulate the data file directly, you should use the data operation function provided by GDBM to access the data.
3.1.
data structure
Data, indexes are saved with the following structure (the same as DBM):
Typedef struct {
CHAR * DPTR;
Int dsize;
} Datum;
The database access structure (equivalent to FILE):
Typedef struct {int Dummy [10];} * gdbm_file;
3.2.
Function introduction
#include
/ * Open Database * /
GDBM_FILE * GDBM_OPEN
Char * name; / * Used to save database path file name * /
INT block_size; / * Sets the unit of memory and disk direct IO, minimum 512 bytes * /
INT read_write; / * can be set to: gdbm_reader, gdbm_writer, gdbm_wrcreater, gdbm_newdb * /
INT MODE; / * file open mode. Similar to CHMOD (2), Open (2) * /
):
Successfully returns the GDBM_FILE type pointer, otherwise returns NULL.
/*Storing data*/
INT GDBM_STORE (GDBM_FILE * DATABASE_DESCRIPTOR, / * Open the structure returned by the database operation * /
Datum key, / * Keywords to retrieve data * /
Datum Content, / * Structure for Save Data * /
Int store_mode / * If you are gdbm_insert, the operation will fail when the data exists. If GDBM_REPLACE, override the existing data * /
); / * Is the same as DBM * /
Returns -1 if a read-only open database calls this function.
If the database is opened in GDBM_INSTERT, and the saved data keyword already exists, then returns 1;
Other situations return 0 (successful operation);
Note: The size of the GDBM stored data is not limited, which is different from DBM, NDBM.
/ * Retrieve data * /
Datum GDBM_FETCH (GDBM_FILE * DATABASE_DESCREIPTOR, / * GDBM_OPEN Returned Data Structure * /
Datum key / * Retrieves keywords * /
); / * Is the same as DBM * /
If the DPTR field of the return value is NULL, the data is not found;
Note: GDBM automatically assigns DPTR's storage (using Malloc (3C)), but does not automatically release this space. The responsibility of the release space is handed over to the programmer.
/ * Close the database * /
Void gdbm_close (GDBM_FILE * DATABASE_DESCRIPTOR); / * GDBM_Open Returned Data Structure * /
/ * Other functions * /
INT GDBM_EXIST (GDBM_FILE DBF, DATUM Key); / * Check the data in the database existed in the database * /
Returns True Represents to find the data, returning false indicates that the data does not exist.
INT GDBM_DELETE (GDBM_FILE * DATABASE_DESCRIPTOR, DATUM Key); / * Delete Index to Key Data * /
Returns 0 indicates that the operation is successful, and -1 means that the data corresponding to the key is found.
Char * gdbm_strerror (gdbm_error errno); / * Convert the error code to an English string. * /
Returns the printable error description string.
INT GDBM_SETOPT (GDBM_FILE DBF, INT OPTION, INT VALUE, INT SIZE); / * Sets the parameters of the open database, you can set the internal Cache size, set fast mode (this function is outdated), open or close the central free data block Storage pool. * /
Returns 0 indicates that the setting operation is successful, and the return -1 indicates that the operation failed.
INT GDBM_FDESC (DBF); / * When multiple users share, set the logo of the open database to the database file. * /
Key = gdbm_firstkey (dBF)
NextKey = GDBM_NEXTKEY (DBF, Key); / * Similar to DBM, used to access all data. * /
E.g:
Key = GDBM_FirstKey (DBF);
While (Key.dptr)
{
NextKey = GDBM_NEXTKEY (DBF, Key);
... / * Processing operation in some cycles * /
Key = nextKey;
}
4.
Research: How does the code are compatible with DBM, GDBM
For different systems, some use DBM (NDBM), and some use GDBM. In order to make the C code accessed by the database with better cross-platform capabilities, we need to partially modify the code, while you need to write different profiles for different platforms. In this way, our database operation code has a stronger platform adaptability.
The specific method is as follows:
1.
First, we write a platform-related Makefile file.
For example, Red Hat Linux 6.1 uses a DBM library, while Red Hat Linux 9.0 uses the compilation file named my_dbm.make, Red Hat Linux 9.0, the Red Hat Linux 9.0 is named MY_DBM.MAKE, and the installation file is named MY_GDBM. .
Platform 1: Support DBM's makefile file, we need to write as follows: dbmlib = -ldbm in my_dbm.make
Platform 2: Support GDBM's makefile file, we need to write the following code in rh_linux_9.0.make:
DBMLIB = -LGDBM
2.
Then, write different header files.
For example, we need to write two profiles, named my_dbm.h, my_gdbm.h, respectively, including different definitions therein.
Platform 1: Support DBM profile, we need to write as follows: MY_DBM.H:
#define ndbm
#include
Platform 2: Supports GDBM profiles, we need to write as follows: MY_GDBM.H:
#define gdbm
#include
3.
Let the user choose to copy different profiles to a configuration file of the same name, give a compiled compilation and installation script with the platform.
For example, the user finds the system configuration information, knows that the current system only supports DBM, then the user needs to copy my_dbm.make to the Makefile of the code and copy my_dbm.h to config.h files.
4.
Modify the database operation code so that the two (or more) database operation functions exist.
For example: modify the code, define the header file from the original
#include
change into
#include "config.h"
Add the function compile statement related to database operations.
#ifdef dbm
DBM * mydb; / * dbm, GDBM database operation pointer type is different! * /
DBM_FETCH (...); / * Other functions is similar, pay attention to some of the number of function parameters! * /
#ENDIF
#ifdef gdbm
GDBM_FILE * MYDB; / * For operation, we choose the same variable name. * /
GDBM_FETCH (...); / * Other functions like * /
#ENDIF
Now, you can say that you have to tell you. However, don't forget to give the document readme, tell the user how to use the platform adaptability in your code (now you only know this feature). This ReadMe document must contain:
1.
How to determine the database used by our platform - you can use Man GDBM, Man DBM;
2.
Compiled with the platform, install the Makefile file copy to which directory;
3.
Copying the CONFIG.H file of which directory related to the platform-related header file;
4.
How to compile, install, use your code;
The front is a little attempt to program the C code cross-platform. Most platform-related features can be done using the methods mentioned earlier. It can also be seen here that the C language code must complete multiple sets of functions, and choose some of the partial compilation and installation of the platform according to the platform characteristics. It is completely different from the cross-platform concept of Java code.