Benutzer-Werkzeuge

Webseiten-Werkzeuge


edv:prg:esql_c:example:db_exec_sql

db_exec_sql

Modul mit einigen (Informix-)DB-Funktionen

db_exec_sql.h:

/*********************************************************************
*
* Autor:   Jürgen Kreick
* Version: 1.0.0 vom 24.11.2010
*
**********************************************************************
*
* Hinweise zum Modul/Quelltext:
*
* In der aktuellen Version werden nur Verbindungen zu einer einzigen
* DB pro Sitzung unterstützt.
* Unterstützung von parallelen Sitzungen (zeitgleiche mehrere DB-Verbindungen zu
* jeweils unterschiedlichen DB) sind momentan nicht geplant.
*
**********************************************************************
*
* Release Notes:
*
* Ver 1.0.0 (vom 24.11.2010):
*	Die erste Version des Moduls. Umfasst (nach aussen) folgende Funktionen:
* 	dbInit(), dbDone(), dbSetIsolation(), dbSetModeWait().
*
**********************************************************************/
 
#ifndef db_exec_sql_h_H
#define db_exec_sql_h_H
 
// Rückgabewerte:
#define RC_DB_OK       0
#define RC_DB_ERR     -1
#define RC_DB_NOTFOUND 100
 
// IsolationsLevel
#define DIRTY_READ       1
// "Dirty Read" und "Uncommitted Read" ist das gleiche
#define UNCOMMITTED_READ 1
#define COMMITTED_READ   2
// Die Liste ist nicht vollständig!
 
// Werte für dbEndTransaction()
#define TRANSACTION_COMMIT      1
#define TRANSACTION_ROLLBACK    2
// Transaktionskontext: ON = erforderlich, OFF = nicht erforderlich
#define TRANSACTION_OFF         0
#define TRANSACTION_ON          1
// Transaktion: IN_OF_TRNS = man befindet sich innerhalb eines Transaktionskontextes, OUT_OF_TRNS = außerhalb
#define TRANSACTION_IN_OF_TRNS  1
#define TRANSACTION_OUT_OF_TRNS 0
 
// Log-Meldungen
#define LOG_FEHLGESCHLAGEN               "fehlgeschlagen."
#define LOG_BEGIN_WORK                   "BEGIN WORK"
#define LOG_BEGIN_WORK_FEHLGESCHLAGEN    "BEGIN WORK fehlgeschlagen."
#define LOG_COMMIT_WORK                  "COMMIT WORK"
#define LOG_COMMIT_WORK_FEHLGESCHLAGEN   "COMMIT WORK fehlgeschlagen."
#define LOG_ROLLBACK_WORK                "ROLLBACK WORK"
#define LOG_ROLLBACK_WORK_FEHLGESCHLAGEN "ROLLBACK WORK fehlgeschlagen."
#define LOG_TRANSACTION_PARAM_ERROR      "Falsche Parameter beim Aufruf von dbEndTransaction()"
 
 
// ******************** Prototypen ****************************************
 
// dbInit() wird ein Mal pro DB-Sitzung aufgerufen und baut eine Verbindung zur
// DB auf.
//
// Parameter:
//
// char *dbName	    : Name der DB (z.B. "test_db@test_system")
// int extLogFileID : externe LogFileID für das Logging-System
//
// Rückgabewert: RC_DB_OK (Erfolg) oder RC_DB_ERR (bei Fehlern)
int dbInit (const char *dbName, int extLogFileID);
 
// dbDone() wird ein Mal pro DB-Sitzung aufgerufen und baut die existierende
// Verbindung zur DB ab.
//
// Parameter: keine.
//
// Rückgabewert: RC_DB_OK (Erfolg) oder RC_DB_ERR (bei Fehlern)
int dbDone ();
 
// dbSetIsolation() setzt den aktuellen IsolationsLevel für die Verbindung
int dbSetIsolation (int level);
 
// dbSetModeWait() setzt die Wartezeit in Sekunden beim Warten auf einen gelockten Satz.
// Negative Werte für "sec" bedeuten kein Warten.
// sec = 0 bedeutet keine Begrenzung beim Warten.
int dbSetModeWait (int sec);
 
// Diese Funktion führt einfache SQLs aus.
// Eingabeparameter:
// sql - SQL-String, der ausgeführt werden soll;
// text - Text (z.B. updated / deleted / inserted) für Massenoperationen
// funktionname - "__func__"-Makro der aufrufenden Funktion (für Trace)
// Ausgabeparameter:
// rows - Falls NULL, wird ignoriert, sonst wird dort bei Erfolg die Zahl durch SQL betroffener Sätze zurück gegeben
int execSimpleSQL (const char *sql, const int *rows, const char *text, const char *modulName, int lineNumber, const char *functName);
 
// Transaktionkontext öffnen (BEGIN WORK;)
int dbBeginTransaction ();
// Transaktion beenden (mit COMMIT WORK; oder ROLLBACK WORK;)
int dbEndTransaction (int transactionEnd);
 
 
/* Everything else goes here */
 
#endif

db_exec_sql.ec:

#include "db_exec_sql.h"
// Wehen Logging:
#include "logging_ext.h"
 
 
// Konstanten:
#define TMP_STR_LEN_MAX	8191
 
#define ON  1
#define OFF 0
 
 
// ******************** lokale Strukturen ****************************************
 
 
// ******************** externe  Variablen ****************************************
 
int dbLogFileID = 0;
 
 
// ******************** lokale Variablen ****************************************
 
int dbConnected = 0; // 0 - keine Verbindung, 1 - Verbindung existiert (oder OFF/ON)
 
// ******************** interne Funktionen ****************************************
 
 
// ******************** export-Funktionen ****************************************
 
int dbInit (const char *dbName, int extLogFileID)
{
	int rc     = RC_OK;
	int rc_SQL = RC_DB_OK;
	char logStr [TMP_STR_LEN_MAX + 1];
 
	EXEC SQL BEGIN DECLARE SECTION;
	char dbDatabase [TMP_STR_LEN_MAX + 1];
	EXEC SQL END DECLARE SECTION;
 
	dbLogFileID = extLogFileID; // Da es von außen gesetzt wird, übernehmen wir es blind (sicherheitstechnisch unkritisch).
 
	memset(logStr,     '\0', sizeof(logStr));
	memset(dbDatabase, '\0', sizeof(dbDatabase));
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	// Plausibilitätsprüfung:
	if (dbName) // dbName existiert?
	{
		strlcpy(dbDatabase, dbName, sizeof(dbDatabase)); // Vor dem trim'men umkopieren
		trimAll(dbDatabase, NULL, sizeof(dbDatabase)); // Von den Leerzeichen links und rechts befreien
		if (strlen(dbDatabase) <= 0) // Der DB-Name darf nicht leer sein
		{
			logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "Fehlerhafter Aufruf: Name der DB ist leer.");
			rc = RC_ERR;
		} // if
	}
	else // dbName darf nicht NULL sein
	{
		logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "Fehlerhafter Aufruf: Parameter 'dbName' ist NULL.");
		rc = RC_ERR;
	} // if
 
 
	if (!rc)
	{
		logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "Es wird versucht eine Verbindung zur DB aufzubauen...");
		if (dbConnected) // Verbindung ist bereits vorhanden
		{
			logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "Eine Verbindung zur DB existiert bereits.");
			rc = RC_ERR;
		} // if
	} // if
 
	if (!rc)
	{
		snprintf(logStr, sizeof(logStr), "Database = [%s]", dbDatabase);
		logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, logStr);
 
		EXEC SQL DATABASE :dbDatabase ;
		if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
	} // if
 
	if (!rc) logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "Verbindung zur DB erfolgreich aufgebaut.");
	else logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "Verbindung zur DB konnte nicht aufgebaut werden.");
 
	if (!rc) dbConnected = ON;
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc);
	return rc;
} // dbInit()
 
 
int dbDone ()
{
	int rc = RC_OK;
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	if (dbConnected) // Verbindung existiert
	{
		// TODO: z.B. Cursor frei geben
	} // if
 
	if (dbConnected) dbConnected = OFF;
	else rc = RC_ERR; // Es gibt keine Verbindung, die abgebaut werden soll.
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc);
	return rc;
} // dbDone()
 
 
int dbSetIsolation (int level)
{
	int rc = RC_OK;
	int rc_SQL = RC_DB_OK;
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	switch (level)
	{
		case DIRTY_READ:
			logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "SET ISOLATION TO DIRTY READ;");
			EXEC SQL SET ISOLATION TO DIRTY READ;
			if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
		break; // case DIRTY_READ
 
		case COMMITTED_READ:
			logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "SET ISOLATION TO COMMITTED READ;");
			EXEC SQL SET ISOLATION TO COMMITTED READ;
			if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
		break; // case COMMITTED_READ
 
		default: rc = RC_ERR;
	} // switch (level)
 
	if (rc) logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "IsolationsLevel konnte nicht gesetzt werden.");
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc);
	return rc;
} // int dbSetIsolation()
 
 
int dbSetModeWait (int sec)
{
	int rc = RC_OK;
	int rc_SQL = RC_DB_OK;
 
	EXEC SQL BEGIN DECLARE SECTION;
	char tmpStrSQL [TMP_STR_LEN_MAX + 1];
	EXEC SQL END DECLARE SECTION;
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	memset(tmpStrSQL, '\0', sizeof(tmpStrSQL));
 
	if (sec < 0) // Kein Warten.
	{
		logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "SET LOCK MODE TO NOT WAIT;");
		EXEC SQL SET LOCK MODE TO NOT WAIT;
		if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
	}
	else if (sec == 0) // Keine Begrenzung beim Warten.
	{
		logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, "SET LOCK MODE TO WAIT;");
		EXEC SQL SET LOCK MODE TO WAIT;
		if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
	}
	else // "sec" Sekunden Warten.
	{
		snprintf(tmpStrSQL, sizeof(tmpStrSQL), "SET LOCK MODE TO WAIT %i;", sec);
		logLog(LOG_NOTICE, dbLogFileID, __FILE__, __LINE__, __func__, tmpStrSQL);
		EXEC SQL EXECUTE IMMEDIATE :tmpStrSQL;
		if (rc_SQL = sqlca.sqlcode) rc = RC_ERR;
	} // if
 
	if (rc) logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, "WaitMode konnte nicht gesetzt werden.");
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc);
	return rc;
} // int dbSetModeWait()
 
 
int execSimpleSQL (const char *sql, const int *rows, const char *text, const char *modulName, int lineNumber, const char *functName) // Führt einfache SQLs aus
{
	int rc_SQL = RC_DB_OK;
	int countRows = 0;
	char tmpStr [TMP_STR_LEN_MAX + 1];
 
	EXEC SQL BEGIN DECLARE SECTION;
	char tmpStrSQL [TMP_STR_LEN_MAX + 1];
	EXEC SQL END DECLARE SECTION;
 
	countRows = 0;
	memset(tmpStr,    '\0', sizeof(tmpStr));
	memset(tmpStrSQL, '\0', sizeof(tmpStrSQL));
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	logLog(LOG_DEBUG, dbLogFileID, __FILE__, __LINE__, __func__, sql);
	strlcpy(tmpStrSQL, sql, sizeof(tmpStrSQL));
	logLog(LOG_INFO, dbLogFileID, __FILE__, __LINE__, __func__, tmpStrSQL);
 
	EXEC SQL EXECUTE IMMEDIATE :tmpStrSQL;
	if (rc_SQL = sqlca.sqlcode)
	{
		logLogRC_SQL(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, LOG_FEHLGESCHLAGEN, tmpStrSQL, rc_SQL);
		snprintf(tmpStr, sizeof(tmpStr), "Aufgerufen aus %s[%d]:%s()", modulName, lineNumber, functName);
		logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, tmpStr);
	}
	else
	{
		countRows = sqlca.sqlerrd[2]; // Anzahl betroffener Saetze uebernehmen
		if (text) // Falls nicht NULL
		{
			snprintf(tmpStr, sizeof(tmpStr), "%d rows %s.", countRows, text);
			logLog(LOG_INFO, dbLogFileID, __FILE__, __LINE__, __func__, tmpStr);
		} // if
		if (rows) // Falls nicht NULL
		{
			// Anzahl betroffener Saetze zurueck geben
			*rows = countRows; // Achtung! Es wird nicht ueberprueft, ob "*rows" ausreichend Platz hat!
		} // if
	} // if
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc_SQL);
	return rc_SQL;
} // execSimpleSQL()
 
 
int dbBeginTransaction () // Transaktionkontext öffnen
{
	int rc_SQL = RC_DB_OK;
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	logLog(LOG_INFO, dbLogFileID, __FILE__, __LINE__, __func__, LOG_BEGIN_WORK);
	EXEC SQL BEGIN WORK;
	if (rc_SQL = sqlca.sqlcode) logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, LOG_BEGIN_WORK_FEHLGESCHLAGEN);
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc_SQL);
	return rc_SQL;
} // dbBeginTransaction()
 
 
 
int dbEndTransaction (int transactionEnd) // Transaktion beenden (mit COMMIT WORK; oder ROLLBACK WORK;)
{
	int rc_SQL = RC_DB_OK;
 
	logEntry(LOG_INFO, dbLogFileID, __FILE__, __func__);
 
	switch (transactionEnd) // Entweder COMMIT WORK; oder ROLLBACK WORK;
	{
		case TRANSACTION_COMMIT: // COMMIT WORK;
			logLog(LOG_INFO, dbLogFileID, __FILE__, __LINE__, __func__, LOG_COMMIT_WORK);
			EXEC SQL COMMIT WORK;
			if (rc_SQL = sqlca.sqlcode) logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, LOG_COMMIT_WORK_FEHLGESCHLAGEN);
		break; // case TRANSACTION_COMMIT:
 
		case TRANSACTION_ROLLBACK: // ROLLBACK WORK;
			logLog(LOG_INFO, dbLogFileID, __FILE__, __LINE__, __func__, LOG_ROLLBACK_WORK);
			EXEC SQL ROLLBACK WORK;
			if (rc_SQL = sqlca.sqlcode) logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, LOG_ROLLBACK_WORK_FEHLGESCHLAGEN);
		break; // case TRANSACTION_ROLLBACK:
 
		default: // Unzulässiger Parameterwert
			logLog(LOG_ERR, dbLogFileID, __FILE__, __LINE__, __func__, LOG_TRANSACTION_PARAM_ERROR);
			rc_SQL = RC_DB_ERR;
	} // switch (transactionEnd)
 
	logExitRC(LOG_INFO, dbLogFileID, __FILE__, __func__, rc_SQL);
	return rc_SQL;
} // dbEndTransaction()
 
// EOF

Stand: 24.11.2010
: Jürgen Kreick

EOF

edv/prg/esql_c/example/db_exec_sql.txt · Zuletzt geändert: 2020/01/11 01:23 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki