/* * NAME * client_func - Creates and Uses a client function. * Calls mi_db_error_raise with MI_SQL msg_type if * divisor is 0. * USAGE * client_func [-d database] [-v value] * * ARGUMENTS * -d database name * -v value by which to divide * * DESCRIPTION * Demonstrate a client function. * * test_func takes two arguments: a value and a divisor, returning * value/divisor. If divisor == 0, it calls mi_db_error_raise with * MI_SQL to report the SQL error. * * Uses error handling and query processing functions in mi_services.c. * * BUILD INSTRUCTIONS * cc -g -I$MI_HOME/h -o client_func client_func.c mi_services.o \ * $MI_HOME/lib/libmi.a -lm * * SAMPLE USAGE * client_func -d test -v 2 * * MODS * 4/11/94 jta works with Montage 2.0.9, libmontage '3.0.1 M' * 6/03/94 jta switched mi_db_error_raise to MI_SQL. * works with Illustra libmi 2.0.12. * 7/22/94 jta works with 2.1 * * $Header: /usr/local/devel/montage/samples/programs/RCS/client_func.c,v 1.4 1994/07/22 23:03:10 jta Exp $ */ #include "mi_services.h" #include #include void clean_up ARGS((MI_CONNECTION *conn)); mi_integer test_func ARGS((int i, int divisor)); /* client function */ static char *argtypes1 [] = { "integer", "integer" }; MI_CONNECTION *conn = NULL; main(argc, argv) int argc; char **argv; { char *Db = NULL, library_ver[50], query[200], *server_query="return release();"; int c, errflg = 0, value = 0; extern char *optarg; extern int optind, atoi(); /* ========== Get command line arguments. ========== */ while ((c = getopt(argc, argv, "d:v:")) != -1) { switch (c) { case 'd': Db = optarg; break; case 'v': value = atoi(optarg); break; case '?': errflg++; break; } } if (errflg || optind < argc) { (void) fprintf(stderr, "usage: %s [-d db -v value]\n", argv[0]); exit(2); } if (mi_add_callback(MI_All_Events, (MI_VOID)all_callback,NULL) == MI_ERROR) die("client_func: Can't set up callback", conn); /* ========== Connect to database ================== */ if ((conn = mi_open(Db, NULL, NULL)) == NULL) die("client_func: connection setup failed", conn); if( mi_library_version (library_ver, sizeof(library_ver) - 1) == MI_ERROR) die("client_func: mi_library_version failed", conn); printf("\nlibmi version = '%s'\n", library_ver); printf("server version= "); if (exec_query(conn, server_query, 0) == MI_ERROR) die("select failed.", conn); /* ========== CleanUp from previous failure ======== */ fprintf(stderr, "\nCleaning up any previous failures; ignore 'drop' errors.\n"); clean_up(conn); /* ========== Create Table & Populate ============== */ printf("\nCreating table and client function.\n"); /* Create a table and insert data into it. */ strcpy(query, "create table star_trek (id integer, name text);"); printf("query = '%s'\n", query); if( exec_query(conn, query, 0) == MI_ERROR ) die("client_func: could not create table", conn); strcpy(query, "insert into star_trek values (1234, 'James T. Kirk');"); printf("query = '%s'\n", query); if( exec_query(conn, query, 0) == MI_ERROR) { clean_up(conn); die("client_func: could not add Captain Kirk", conn); } strcpy(query, "insert into star_trek values (2345, 'Spock');"); printf("query = '%s'\n", query); if( exec_query(conn, query, 0) == MI_ERROR) { clean_up(conn); die("client_func: could not add Mr. Spock", conn); } strcpy(query, "insert into star_trek values (3456, 'Leonard McCoy');"); printf("query = '%s'\n", query); if( exec_query(conn, query, 0) == MI_ERROR) { clean_up(conn); die("client_func: could not add Dr. McCoy", conn); } /* ========== Create and register client function ========== */ strcpy(query, "create function test_func (integer, integer) returns integer with (client) as external name '/tmp/goofy.so' language C;"); printf("query = '%s'\n", query); if( exec_query(conn, query, 0) == MI_ERROR) { clean_up(conn); die("client_func: could not create 'test_func'.", conn); } if(mi_register_func ((void *)test_func, "test_func", 2, argtypes1) == MI_ERROR) { clean_up(conn); die("client_func: could not register 'test_func'.", conn); } fprintf(stdout, "Registered client function 'test_func'.\n"); /* ========== Do a query with the client function === */ sprintf(query, "select id, test_func(id, %d) as DivBy%d, name from star_trek;", value, value); printf("\nquery = '%s'\n\n", query); if (exec_query(conn, query, 1) == MI_ERROR) { clean_up(conn); die("client_func: select failed.", conn); } /* ========== Clean Up and Exit ========== */ clean_up(conn); if (mi_close(conn) == MI_ERROR) die("can't close connection", NULL); else exit(0); } mi_integer test_func(i, divisor) int i; int divisor; { if (divisor == 0) { mi_db_error_raise(conn, MI_SQL, "22012", 0); /* doesn't get this far */ } return (i/divisor); } void clean_up(conn) MI_CONNECTION *conn; { char *query; query = "drop table star_trek;"; fprintf(stderr, "\nclean_up: query = '%s'\n", query); (void) exec_query(conn, query, 0); query = "drop function test_func (integer, integer);"; fprintf(stderr, "clean_up: query = '%s'\n", query); (void) exec_query(conn, query, 0); return; }