From 746626e78f27849c603fc89eeab9d9093d0fa4dd Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Mon, 5 Apr 2010 13:38:12 +0200 Subject: [PATCH] Add support for transactions. Normal operations for Ingres is to make things one big transaction. The old code never commits anything and as such you loose all state on exit of the dird. Now we always commit our work unless we are in a transaction. --- bacula/src/cats/ingres.c | 26 +++++- bacula/src/cats/myingres.c | 176 +++++++++++++++++++++++++----------- bacula/src/cats/myingres.h | 7 +- bacula/src/cats/myingres.sc | 52 +++++++++-- bacula/src/cats/myingres.sh | 7 +- 5 files changed, 199 insertions(+), 69 deletions(-) diff --git a/bacula/src/cats/ingres.c b/bacula/src/cats/ingres.c index 3f82cc32c2..7a483d5fec 100755 --- a/bacula/src/cats/ingres.c +++ b/bacula/src/cats/ingres.c @@ -551,15 +551,35 @@ int my_ingres_query(B_DB *mdb, const char *query) Dmsg1(500, "my_ingres_query starts with '%s'\n", new_query); + /* + * See if we are getting a transaction start or end. + */ + if (strcasecmp(new_query, "BEGIN") != NULL) { + /* + * Start of a transaction. + */ + Dmsg0(500,"my_ingres_query: Start of transaction\n"); + mdb->transaction = true; + return 0; + } else if (strcasecmp(new_query, "END") != NULL) { + /* + * End of a transaction. + */ + Dmsg0(500,"my_ingres_query: End of transaction, commiting work\n"); + mdb->transaction = false; + INGcommit(mdb->db); + return 0; + } + /* TODO: differentiate between SELECTs and other queries */ - if ((cols = INGgetCols(mdb->db, new_query)) <= 0) { + if ((cols = INGgetCols(mdb->db, new_query, mdb->transaction)) <= 0) { if (cols < 0 ) { Dmsg0(500,"my_ingres_query: neg.columns: no DML stmt!\n"); } Dmsg0(500,"my_ingres_query (non SELECT) starting...\n"); /* non SELECT */ - mdb->num_rows = INGexec(mdb->db, new_query); + mdb->num_rows = INGexec(mdb->db, new_query, mdb->transaction); if (INGcheck()) { Dmsg0(500,"my_ingres_query (non SELECT) went wrong\n"); mdb->status = 1; @@ -570,7 +590,7 @@ int my_ingres_query(B_DB *mdb, const char *query) } else { /* SELECT */ Dmsg0(500,"my_ingres_query (SELECT) starting...\n"); - mdb->result = INGquery(mdb->db, new_query); + mdb->result = INGquery(mdb->db, new_query, mdb->transaction); if (mdb->result != NULL) { Dmsg1(500, "we have a result\n", new_query); diff --git a/bacula/src/cats/myingres.c b/bacula/src/cats/myingres.c index f9bd3f6279..728a0668d8 100644 --- a/bacula/src/cats/myingres.c +++ b/bacula/src/cats/myingres.c @@ -54,7 +54,7 @@ int INGcheck() { return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0; } -short INGgetCols(INGconn *conn, const char *query) +short INGgetCols(INGconn *conn, const char *query, bool transaction) { /* # line 57 "myingres.sc" */ @@ -98,24 +98,35 @@ short INGgetCols(INGconn *conn, const char *query) } number = sqlda->sqld; bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { +/* # line 97 "myingres.sc" */ /* commit */ + { + IIsqInit(&sqlca); + IIxact(3); + } +/* # line 98 "myingres.sc" */ /* host code */ + } /* * Switch to no default session for this thread. */ -/* # line 96 "myingres.sc" */ /* set_sql */ +/* # line 102 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } -/* # line 97 "myingres.sc" */ /* host code */ +/* # line 103 "myingres.sc" */ /* host code */ free(stmt); free(sqlda); return number; } static inline IISQLDA *INGgetDescriptor(short numCols, const char *query) { -/* # line 104 "myingres.sc" */ +/* # line 110 "myingres.sc" */ char *stmt; -/* # line 106 "myingres.sc" */ +/* # line 112 "myingres.sc" */ int i; IISQLDA *sqlda; @@ -123,12 +134,12 @@ static inline IISQLDA *INGgetDescriptor(short numCols, const char *query) memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE))); sqlda->sqln = numCols; stmt = bstrdup(query); -/* # line 118 "myingres.sc" */ /* prepare */ +/* # line 124 "myingres.sc" */ /* prepare */ { IIsqInit(&sqlca); IIsqPrepare(0,(char *)"s2",sqlda,0,stmt); } -/* # line 120 "myingres.sc" */ /* host code */ +/* # line 126 "myingres.sc" */ /* host code */ free(stmt); for (i = 0; i < sqlda->sqld; ++i) { /* @@ -353,32 +364,32 @@ static inline int INGfetchAll(const char *query, INGresult *ing_res) IISQLDA *desc; int check = -1; desc = ing_res->sqlda; -/* # line 374 "myingres.sc" */ /* host code */ +/* # line 380 "myingres.sc" */ /* host code */ if ((check = INGcheck()) < 0) { return check; } -/* # line 378 "myingres.sc" */ /* open */ +/* # line 384 "myingres.sc" */ /* open */ { IIsqInit(&sqlca); - IIcsOpen((char *)"c2",22166,10460); + IIcsOpen((char *)"c2",19193,19709); IIwritio(0,(short *)0,1,32,0,(char *)"s2"); - IIcsQuery((char *)"c2",22166,10460); + IIcsQuery((char *)"c2",19193,19709); } -/* # line 379 "myingres.sc" */ /* host code */ +/* # line 385 "myingres.sc" */ /* host code */ if ((check = INGcheck()) < 0) { return check; } /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */ do { -/* # line 385 "myingres.sc" */ /* fetch */ +/* # line 391 "myingres.sc" */ /* fetch */ { IIsqInit(&sqlca); - if (IIcsRetScroll((char *)"c2",22166,10460,-1,-1) != 0) { + if (IIcsRetScroll((char *)"c2",19193,19709,-1,-1) != 0) { IIcsDaGet(0,desc); IIcsERetrieve(); } /* IIcsRetrieve */ } -/* # line 387 "myingres.sc" */ /* host code */ +/* # line 393 "myingres.sc" */ /* host code */ if ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ) { row = INGgetRowSpace(ing_res); /* alloc space for fetched row */ /* @@ -395,12 +406,12 @@ static inline int INGfetchAll(const char *query, INGresult *ing_res) ++linecount; } } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ); -/* # line 405 "myingres.sc" */ /* close */ +/* # line 411 "myingres.sc" */ /* close */ { IIsqInit(&sqlca); - IIcsClose((char *)"c2",22166,10460); + IIcsClose((char *)"c2",19193,19709); } -/* # line 407 "myingres.sc" */ /* host code */ +/* # line 413 "myingres.sc" */ /* host code */ ing_res->status = ING_COMMAND_OK; ing_res->num_rows = linecount; return linecount; @@ -465,15 +476,15 @@ short INGftype(const INGresult *res, int column_number) { return res->fields[column_number].type; } -int INGexec(INGconn *conn, const char *query) +int INGexec(INGconn *conn, const char *query, bool transaction) { int check; -/* # line 488 "myingres.sc" */ +/* # line 494 "myingres.sc" */ int sess_id; int rowcount; char *stmt; -/* # line 492 "myingres.sc" */ +/* # line 498 "myingres.sc" */ stmt = bstrdup(query); rowcount = -1; @@ -481,43 +492,54 @@ int INGexec(INGconn *conn, const char *query) * Switch to the correct default session for this thread. */ sess_id = conn->session_id; -/* # line 501 "myingres.sc" */ /* set_sql */ +/* # line 507 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } -/* # line 502 "myingres.sc" */ /* execute */ +/* # line 508 "myingres.sc" */ /* execute */ { IIsqInit(&sqlca); IIsqExImmed(stmt); IIsyncup((char *)0,0); } -/* # line 504 "myingres.sc" */ /* host code */ +/* # line 510 "myingres.sc" */ /* host code */ free(stmt); if ((check = INGcheck()) < 0) { rowcount = check; goto bail_out; } -/* # line 511 "myingres.sc" */ /* inquire_ingres */ +/* # line 517 "myingres.sc" */ /* inquire_ingres */ { IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8); } -/* # line 512 "myingres.sc" */ /* host code */ +/* # line 518 "myingres.sc" */ /* host code */ if ((check = INGcheck()) < 0) { rowcount = check; goto bail_out; } bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { +/* # line 528 "myingres.sc" */ /* commit */ + { + IIsqInit(&sqlca); + IIxact(3); + } +/* # line 529 "myingres.sc" */ /* host code */ + } /* * Switch to no default session for this thread. */ -/* # line 521 "myingres.sc" */ /* set_sql */ +/* # line 533 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } -/* # line 522 "myingres.sc" */ /* host code */ +/* # line 534 "myingres.sc" */ /* host code */ return rowcount; } -INGresult *INGquery(INGconn *conn, const char *query) +INGresult *INGquery(INGconn *conn, const char *query, bool transaction) { /* * TODO: error handling @@ -526,20 +548,20 @@ INGresult *INGquery(INGconn *conn, const char *query) INGresult *res = NULL; int rows = -1; int cols = INGgetCols(conn, query); -/* # line 534 "myingres.sc" */ +/* # line 546 "myingres.sc" */ int sess_id; -/* # line 536 "myingres.sc" */ +/* # line 548 "myingres.sc" */ /* * Switch to the correct default session for this thread. */ sess_id = conn->session_id; -/* # line 542 "myingres.sc" */ /* set_sql */ +/* # line 554 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id); } -/* # line 544 "myingres.sc" */ /* host code */ +/* # line 556 "myingres.sc" */ /* host code */ desc = INGgetDescriptor(cols, query); if (!desc) { goto bail_out; @@ -556,14 +578,25 @@ INGresult *INGquery(INGconn *conn, const char *query) goto bail_out; } bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { +/* # line 580 "myingres.sc" */ /* commit */ + { + IIsqInit(&sqlca); + IIxact(3); + } +/* # line 581 "myingres.sc" */ /* host code */ + } /* * Switch to no default session for this thread. */ -/* # line 567 "myingres.sc" */ /* set_sql */ +/* # line 585 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } -/* # line 568 "myingres.sc" */ /* host code */ +/* # line 586 "myingres.sc" */ /* host code */ return res; } void INGclear(INGresult *res) @@ -574,6 +607,41 @@ void INGclear(INGresult *res) INGfreeDescriptor(res->sqlda); INGfreeINGresult(res); } +void INGcommit(onst INGconn *conn) +{ +/* # line 601 "myingres.sc" */ + + int sess_id; +/* # line 603 "myingres.sc" */ + + if (dbconn != NULL) { + sess_id = dbconn->session_id; +/* # line 607 "myingres.sc" */ /* disconnect */ + { + IIsqInit(&sqlca); + IILQsidSessID(sess_id); + IIsqDisconnect(); + } +/* # line 609 "myingres.sc" */ /* host code */ + /* + * Commit our work. + */ +/* # line 612 "myingres.sc" */ /* commit */ + { + IIsqInit(&sqlca); + IIxact(3); + } +/* # line 614 "myingres.sc" */ /* host code */ + /* + * Switch to no default session for this thread. + */ +/* # line 617 "myingres.sc" */ /* set_sql */ + { + IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); + } +/* # line 618 "myingres.sc" */ /* host code */ + } +} INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) { INGconn *dbconn; @@ -582,13 +650,13 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) } dbconn = (INGconn *)malloc(sizeof(INGconn)); memset(dbconn, 0, sizeof(INGconn)); -/* # line 592 "myingres.sc" */ +/* # line 632 "myingres.sc" */ char ingdbname[24]; char ingdbuser[32]; char ingdbpasswd[32]; int sess_id; -/* # line 597 "myingres.sc" */ +/* # line 637 "myingres.sc" */ sess_id = session_id; bstrncpy(ingdbname, dbname, sizeof(ingdbname)); @@ -599,7 +667,7 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) } else { memset(ingdbpasswd, 0, sizeof(ingdbpasswd)); } -/* # line 609 "myingres.sc" */ /* connect */ +/* # line 649 "myingres.sc" */ /* connect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); @@ -608,9 +676,9 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0); } -/* # line 614 "myingres.sc" */ /* host code */ +/* # line 654 "myingres.sc" */ /* host code */ } else { -/* # line 615 "myingres.sc" */ /* connect */ +/* # line 655 "myingres.sc" */ /* connect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); @@ -618,7 +686,7 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0); } -/* # line 618 "myingres.sc" */ /* host code */ +/* # line 658 "myingres.sc" */ /* host code */ } if (INGcheck() < 0) { return NULL; @@ -632,45 +700,45 @@ INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) /* * Switch to no default session for this thread undo default settings from SQL CONNECT. */ -/* # line 633 "myingres.sc" */ /* set_sql */ +/* # line 673 "myingres.sc" */ /* set_sql */ { IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97)); } -/* # line 635 "myingres.sc" */ /* host code */ +/* # line 675 "myingres.sc" */ /* host code */ return dbconn; } void INGdisconnectDB(INGconn *dbconn) { -/* # line 640 "myingres.sc" */ +/* # line 680 "myingres.sc" */ int sess_id; -/* # line 642 "myingres.sc" */ +/* # line 682 "myingres.sc" */ - sess_id = dbconn->session_id; -/* # line 645 "myingres.sc" */ /* disconnect */ + if (dbconn != NULL) { + sess_id = dbconn->session_id; +/* # line 686 "myingres.sc" */ /* disconnect */ { IIsqInit(&sqlca); IILQsidSessID(sess_id); IIsqDisconnect(); } -/* # line 647 "myingres.sc" */ /* host code */ - if (dbconn != NULL) { +/* # line 688 "myingres.sc" */ /* host code */ free(dbconn->msg); free(dbconn); } } char *INGerrorMessage(const INGconn *conn) { -/* # line 655 "myingres.sc" */ +/* # line 695 "myingres.sc" */ char errbuf[256]; -/* # line 657 "myingres.sc" */ +/* # line 697 "myingres.sc" */ -/* # line 659 "myingres.sc" */ /* inquire_ingres */ +/* # line 699 "myingres.sc" */ /* inquire_ingres */ { IILQisInqSqlio((short *)0,1,32,255,errbuf,63); } -/* # line 660 "myingres.sc" */ /* host code */ +/* # line 700 "myingres.sc" */ /* host code */ memcpy(conn->msg, &errbuf, 256); return conn->msg; } @@ -682,5 +750,5 @@ char *INGcmdTuples(INGresult *res) int INGputCopyEnd(INGconn *conn, const char *errormsg); int INGputCopyData(INGconn *conn, const char *buffer, int nbytes); */ -/* # line 674 "myingres.sc" */ +/* # line 714 "myingres.sc" */ #endif diff --git a/bacula/src/cats/myingres.h b/bacula/src/cats/myingres.h index dbe2309bcc..e89315ec0a 100644 --- a/bacula/src/cats/myingres.h +++ b/bacula/src/cats/myingres.h @@ -70,16 +70,17 @@ typedef struct ing_conn { } INGconn; /* ---Prototypes--- */ int INGcheck(void); -short INGgetCols(INGconn *conn, const char *query); +short INGgetCols(INGconn *conn, const char *query. bool transaction); char *INGgetvalue(INGresult *res, int row_number, int column_number); bool INGgetisnull(INGresult *res, int row_number, int column_number); int INGntuples(const INGresult *res); int INGnfields(const INGresult *res); char *INGfname(const INGresult *res, int column_number); short INGftype(const INGresult *res, int column_number); -int INGexec(INGconn *db, const char *query); -INGresult *INGquery(INGconn *db, const char *query); +int INGexec(INGconn *db, const char *query. bool transaction); +INGresult *INGquery(INGconn *db, const char *query. bool transaction); void INGclear(INGresult *res); +void INGcommit(onst INGconn *conn); INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id); void INGdisconnectDB(INGconn *dbconn); char *INGerrorMessage(const INGconn *conn); diff --git a/bacula/src/cats/myingres.sc b/bacula/src/cats/myingres.sc index 3071572122..5f0b210851 100644 --- a/bacula/src/cats/myingres.sc +++ b/bacula/src/cats/myingres.sc @@ -52,7 +52,7 @@ int INGcheck() return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0; } -short INGgetCols(INGconn *conn, const char *query) +short INGgetCols(INGconn *conn, const char *query, bool transaction) { EXEC SQL BEGIN DECLARE SECTION; int sess_id; @@ -90,6 +90,12 @@ short INGgetCols(INGconn *conn, const char *query) number = sqlda->sqld; bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { + EXEC SQL COMMIT WORK; + } /* * Switch to no default session for this thread. */ @@ -482,7 +488,7 @@ short INGftype(const INGresult *res, int column_number) return res->fields[column_number].type; } -int INGexec(INGconn *conn, const char *query) +int INGexec(INGconn *conn, const char *query, bool transaction) { int check; EXEC SQL BEGIN DECLARE SECTION; @@ -515,6 +521,12 @@ int INGexec(INGconn *conn, const char *query) } bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { + EXEC SQL COMMIT WORK; + } /* * Switch to no default session for this thread. */ @@ -522,7 +534,7 @@ bail_out: return rowcount; } -INGresult *INGquery(INGconn *conn, const char *query) +INGresult *INGquery(INGconn *conn, const char *query, bool transaction) { /* * TODO: error handling @@ -561,6 +573,12 @@ INGresult *INGquery(INGconn *conn, const char *query) } bail_out: + /* + * If we are not in a transaction we commit our work now. + */ + if (!transaction) { + EXEC SQL COMMIT WORK; + } /* * Switch to no default session for this thread. */ @@ -578,6 +596,28 @@ void INGclear(INGresult *res) INGfreeINGresult(res); } +void INGcommit(onst INGconn *conn) +{ + EXEC SQL BEGIN DECLARE SECTION; + int sess_id; + EXEC SQL END DECLARE SECTION; + + if (dbconn != NULL) { + sess_id = dbconn->session_id; + EXEC SQL DISCONNECT SESSION :sess_id; + + /* + * Commit our work. + */ + EXEC SQL COMMIT WORK; + + /* + * Switch to no default session for this thread. + */ + EXEC SQL SET_SQL (SESSION = NONE); + } +} + INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id) { INGconn *dbconn; @@ -641,10 +681,10 @@ void INGdisconnectDB(INGconn *dbconn) int sess_id; EXEC SQL END DECLARE SECTION; - sess_id = dbconn->session_id; - EXEC SQL DISCONNECT SESSION :sess_id; - if (dbconn != NULL) { + sess_id = dbconn->session_id; + EXEC SQL DISCONNECT SESSION :sess_id; + free(dbconn->msg); free(dbconn); } diff --git a/bacula/src/cats/myingres.sh b/bacula/src/cats/myingres.sh index a41b87ca1a..cb554a47e9 100644 --- a/bacula/src/cats/myingres.sh +++ b/bacula/src/cats/myingres.sh @@ -83,16 +83,17 @@ typedef struct ing_conn { /* ---Prototypes--- */ int INGcheck(void); -short INGgetCols(INGconn *conn, const char *query); +short INGgetCols(INGconn *conn, const char *query. bool transaction); char *INGgetvalue(INGresult *res, int row_number, int column_number); bool INGgetisnull(INGresult *res, int row_number, int column_number); int INGntuples(const INGresult *res); int INGnfields(const INGresult *res); char *INGfname(const INGresult *res, int column_number); short INGftype(const INGresult *res, int column_number); -int INGexec(INGconn *db, const char *query); -INGresult *INGquery(INGconn *db, const char *query); +int INGexec(INGconn *db, const char *query. bool transaction); +INGresult *INGquery(INGconn *db, const char *query. bool transaction); void INGclear(INGresult *res); +void INGcommit(onst INGconn *conn); INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id); void INGdisconnectDB(INGconn *dbconn); char *INGerrorMessage(const INGconn *conn); -- 2.39.5