Examples of Scripts
Create Table
/*
** Simple script file to create a database table.
*/
#include "include/dmutil.h" /* Get names of externs and defines */
#include "include/dbase.h"
main()
{
DB_TBL_NAME("POOP"); /* First we'll name the table */
DB_TBL_COLUMN("Name", /* Then define each column */
DB_COL_TYPE("STRING"),
DB_COL_LEN(16),
DB_COL_ISKEY(1)); /* Name is used as the key */
DB_TBL_COLUMN("Description",
DB_COL_TYPE("STRING"),
DB_COL_LEN(64),
DB_COL_VARLEN(1));
DB_TBL_COLUMN("Size",
DB_COL_TYPE("INT"),
DB_COL_MIN(10),
DB_COL_MAX(2000));
DB_TBL_COLUMN("Weight",
DB_COL_TYPE("FLOAT"),
DB_COL_QUANT("Mass"),
DB_COL_MIN(0.1),
DB_COL_MAX(10000));
DB_TBL_COLUMN("Price",
DB_COL_TYPE("FLOAT"),
DB_COL_EDITABLE(0));
/* Finally request server to create the table*/
if (DB_TBL_CREATE() == 0)
U_MESSAGE("Table `POOP' created");
return(0);
}
Edit Records in Table
/*
** This example script allows the user to edit records in table `POOP'.
** Panel that contains the necessary buttons is named "EditDbTbl.p"
** and we expect to be able to locate it in directory
** $PMS_HOME/dm/$PMS_LANG/panel
*/
#include "include/dmutil.h"
#include "include/dbase.h"
main()
{
t = DB_TBL_OPEN("POOP");
if (t == 0) return(-1);
/*
** Notice that field `Price' will not appear in the panel since it
** was marked as being not editable. Some special macro could be
** used to to set this value. This demonstrates how
** you can keep the dirty hands of the user off your valuable data.
**
** If function DB_FULL_IMAGE() was used to get the image then fields
** would not necessarily be in the order in which we want them to be
** in the edit panel.
**
** If the order of fields would not be of any importance then
** we could use function DB_FULL_IMAGE() and this macro could
** be parameterized so that the name of the table to edit is passed
** as an argument.
*/
image = DB_REC_IMAGE(t, "Name", "Description", "Size", "Price", "Weight");
if (image == 0) {
DB_TBL_CLOSE(t);
return(-1);
}
p_path = SYS_GETENV("PMS_HOME");
p_path = APPEND(p_path, "/dm/");
p_path = APPEND(p_path, SYS_GETENV("PMS_LANG"));
p_path = APPEND(p_path, "/panel"); /* this is intrinsic script func. */
panel = DB_LOAD_DYNPANEL("EditDbTbl.p", p_path);
if (panel == 0) {
DB_TBL_CLOSE(t);
return(-1);
}
/* Create panel items to match fields in the image */
if (DB_EDIT_FIELDS(panel, t, image) != 0) {
W_DESTROY_DYNPANEL(panel);
DB_TBL_CLOSE(t);
return(-1);
}
/* Popup panel and let the user modify records. */
W_POPUP_DYNPANEL(panel);
DB_RUN_EDIT(panel, t, image, "", ""); /* no help file specified */
/* Clean up */
W_DESTROY_DYNPANEL(panel);
DB_TBL_CLOSE(t);
return(0);
}
Dump Contents of Table to ASCII
/*
** Macro that saves contents of table POOP into file poop.bck so that
** the table can later be loaded from this file.
** This reloading is necessary if the structure of the table is changed.
*/
#include include/dmutil.h
#include include/dbase.h
main()
{
t = DB_TBL_OPEN("POOP");
if (t == 0) {
U_MESSAGE("Cannot open table `POOP'");
return(-1);
}
r = DB_REC_IMAGE(t, "Name", "Description", "Size", "Weight", "Price");
fname = "poop.bck";
if (F_EXIST(fname) == 0)
F_CREATE_FILE(fname);
f = F_OPEN_FILE(fname, "w");
if (f < 0) {
U_MESSAGE("Cannot open file `poop.bck' for writing");
DB_TBL_CLOSE(t);
}
go_on = 1;
DB_SELECT_RECS(t, "*"); /* full search */
st = 0;
nr = 0;
while (go_on > 0) {
rec = DB_NEXT_REC(t, r, go_on);
get_failed = 0;
if (go_on > 0) {
name = DB_GET_FIELD(r, "Name", st);
if (st != 0) get_failed = get_failed + 1;
desc = DB_GET_FIELD(r, "Description", st);
if (st != 0) get_failed = get_failed + 1;
size = DB_GET_FIELD(r, "Size", st);
if (st != 0) get_failed = get_failed + 1;
price = DB_GET_FIELD(r, "Price", st);
if (st != 0) get_failed = get_failed + 1;
weight = DB_GET_FIELD(r, "Weight", st);
if (st != 0) get_failed = get_failed + 1;
if (get_failed == 0) {
recno = DB_RECNUMBER(rec);
seal = DB_RECSEAL(rec);
/*
** Values of fields will be printed to the file using
** different techniques. For strings the only proper way
** to print is to call F_WRITE_FIELD. This function handles
** embedded newlines and other funnies automatically.
** If we were printing a report then we could print strings
** the same way as other variables.
*/
len = F_WRITE_INT(f, recno);
len = len + F_WRITE_INT(f, seal);
len = F_WRITE_FIELD(f, name, len);
len = F_WRITE_FIELD(f, desc, len);
if (len > 60)
F_WRITE_NEWLINE(f);
F_PRINTF(f, "%d %g %g\n", size, price, weight);
nr = nr + 1;
}
}
if (get_failed > 0) {
U_MESSAGE("Error accessing table `POOP'");
go_on = 0; /* terminates outer loop */
}
}
U_MESSAGE(ITOASCII(nr) + " records written to `poop.bck'");
F_CLOSE_FILE(f);
DB_TBL_CLOSE(t);
return(0);
}
Delete Table
/*
** Script to delete a table.
*/
extern DB_TBL_DELETE;
extern U_YESNO, U_MESSAGE;
main()
{
if (U_YESNO("Really want to delete table `POOP' ?", 1) == 1) {
DB_TBL_DELETE("POOP");
U_MESSAGE("Table `POOP' deleted");
}
}
Reload Table from ASCII File
/*
** Script that reloads table POOP with data read from file poop.bck.
*/
#include "include/dmutil.h"
#include "include/dbase.h"
main()
{
t = DB_TBL_OPEN("POOP");
if (t == 0) {
return(-1);
}
r = DB_REC_IMAGE(t, "Name", "Description", "Size", "Price", "Weight");
if (r == 0) {
DB_TBL_CLOSE(t);
return(-1);
}
fname = "poop.bck";
f = F_OPEN_FILE(fname, "r");
if (f < 0) {
U_MESSAGE("Cannot open file `poop.bck'");
DB_TBL_CLOSE(t);
return(-1);
}
recno = 0; recseal = 0; name = ""; desc = ""; size = 0; price =0;
weight = 0;
go_on = 1;
nr = 0; /* counts the nr of loaded records */
error = 0;
while (go_on > 0) {
if (F_READ_INT(f, recno) != 1) {
U_MESSAGE(ITOASCII(nr) + " records loaded into table `POOP'");
F_CLOSE_FILE(f);
DB_TBL_CLOSE(t);
return(0);
}
if (F_READ_INT(f, recseal) != 1) go_on = 0;
if (F_READ_FIELD(f, name) < 1) go_on = 0;
if (F_READ_FIELD(f, desc) < 1) go_on = 0;
if (F_READ_INT(f, size) != 1) go_on = 0;
if (F_READ_FLOAT(f, price) != 1) go_on = 0;
if (F_READ_FLOAT(f, weight) != 1) go_on = 0;
if (go_on == 0) {
U_MESSAGE("Failed to read data for record `" + ITOASCII(recno) +
"' from file `poop.bck'");
}
else {
if (DB_SET_FIELD(r, "Size", size) != 0) go_on = 0;
if (DB_SET_FIELD(r, "Price", price) != 0) go_on = 0;
if (DB_SET_FIELD(r, "Weight", weight) != 0) go_on = 0;
if (DB_SET_FIELD(r, "Name", name) != 0) go_on = 0;
if (DB_SET_FIELD(r, "Description",desc) != 0) go_on = 0;
if (go_on == 0) {
U_MESSAGE("Error setting value of field");
}
else {
if (DB_LOAD_REC(t, r, recno, recseal, error) == 0) {
U_MESSAGE("Error re-loading record `" + ITOASCII(recno) +
"' into table `POOP'");
go_on = 0;
}
else {
nr = nr + 1;
}
}
}
}
U_MESSAGE("!!! Failed to reload table `POOP' completely");
U_MESSAGE(ITOASCII(nr) + " records were loaded");
F_CLOSE_FILE(f);
DB_TBL_CLOSE(t);
}
include file load_dbt.h
/*
** This script reloads a dbase table.
** Script included into scripts that rebuild a database.
*/
load_dbtable(STRING tbl_name, STRING tblf, int nr_recs) {
not_built = tbl_name + " : NOT REBUILT";
f = F_OPEN_FILE(tblf, "r");
if (f < 0) {
U_MESSAGE("Failed to open file " + tblf);
U_MESSAGE(not_built);
return(-1);
}
t = DB_TBL_OPEN(tbl_name);
if (t == 0) {
U_MESSAGE(not_built);
F_CLOSE_FILE(f);
return(-1);
}
image = DB_FULL_IMAGE(t);
nr_unl = DB_TBL_LOAD(f, t, image, nr_recs);
if (nr_unl < 0) {
U_MESSAGE(not_built);
}
else {
if (nr_unl > 0) {
U_MESSAGE(tbl_name + " : NOT completely rebuilt");
U_MESSAGE(ITOASCII(nr_unl) + " records not loaded");
}
else {
U_MESSAGE(tbl_name + " : " + ITOASCII(nr_recs) + " records reloaded");
}
}
DB_TBL_CLOSE(t);
F_CLOSE_FILE(f);
return(nr_unl);
}
Backup Database
/*
** This script creates a backup of the database, both its structure and
** contents. The database can be later rebuilt in any host type.
**
** This script generates one script file and ascii data
** files for each table in the database. The script file is named
** `rebuild.mac'. When run it rebuilds the database.
**
*/
#include "include/dmutil.h"
#include "include/dbase.h"
open_file(STRING fname, STRING mode)
{
if (mode == "w") {
if (F_EXIST(fname) == 0)
F_CREATE_FILE(fname);
}
f = F_OPEN_FILE(fname, mode);
if (f < 0)
U_MESSAGE("Failed to open file " + fname);
return(f);
}
main()
{
macro = "rebuild.mac";
f = open_file(macro, "w");
if (f < 0) {
return(-1);
}
/* Add statements to include extern definitions */
F_PRINTF(f, "#include include/dmutil.h\n");
F_PRINTF(f, "#include include/dbase.h\n");
F_PRINTF(f, "#include include/load_dbt.mac\n");
/* handle each table */
go_on = 1;
nth = 1;
if (DB_LOCK_SERVER() != 0) {
U_MESSAGE("Cannot lock server. Not safe to do backup.");
F_CLOSE_FILE(f);
}
while (go_on == 1) {
tbl_name = DB_GET_NTH_TABLE(nth);
if (tbl_name != "") {
if (dump_table(f, nth, tbl_name) != 0) {
U_MESSAGE("Failed to dump table " + tbl_name);
F_CLOSE_FILE(f);
U_MESSAGE("Backup of database failed");
DB_UNLOCK_SERVER();
return(-1);
}
nth = nth + 1;
}
else
go_on = 0;
}
DB_UNLOCK_SERVER();
/* Create script `main' that calls each table builder script */
F_PRINTF(f, "\nmain()\n{\n");
i = 1;
while (i < nth) {
F_PRINTF(f, " BuildTbl%d();\n", i);
i = i + 1;
}
F_PRINTF(f, "}\n");
F_CLOSE_FILE(f);
U_MESSAGE("Database backed up. " + ITOASCII(nth - 1) + " tables");
return(0);
}
dump_table(int f, int nth, STRING tbl_name){
t = DB_TBL_OPEN(tbl_name);
if (t == 0) return(-1);
F_PRINTF(f, "BuildTbl%d()\n{\n", nth);
/* Dump statements that when run will create the table */
DB_TBL_DESCRIBE(f, t);
/* Dump contents of the table into file tblxxx.dmp and then
add statements into script to reload the table */
tblf = "";
S_PRINTF(tblf, "tbl%d.dmp", nth);
df = open_file(tblf, "w");
if (df < 0) {
DB_TBL_CLOSE(t);
return(-1);
}
image = DB_FULL_IMAGE(t);
nr_recs = DB_TBL_DUMP(df, t, image);
if (nr_recs < 0) {
U_MESSAGE("Failed to dump table " + tbl_name);
DB_TBL_CLOSE(t);
F_CLOSE_FILE(df);
return(-1);
}
F_CLOSE_FILE(df);
DB_TBL_CLOSE(t);
U_MESSAGE("Table " + tbl_name + " : " + ITOASCII(nr_recs) + " records");
if (nr_recs > 0) {
F_PRINTF(f, # load_dbtable("%s","%s",%d);\n#,
tbl_name, tblf, nr_recs);
}
else {
F_DELETE_FILE(tblf); /* no records, no need to keep the dumpfile */
}
F_PRINTF(f, "}\n");
return(0);
}