📄 ecpglib.c
字号:
break; default: break; } sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; variable->len = var->varcharsize; } } break; default: register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", ECPGtype_name(var->type), stmt->lineno); status = false; break; } } var = var->next; } if (status && var != NULL) { register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno); status = false; } break; case PGRES_EMPTY_QUERY: /* do nothing */ register_error(ECPG_EMPTY, "Empty query line %d.", stmt->lineno); break; case PGRES_COMMAND_OK: status = true; sqlca.sqlerrd[2] = atol(PQcmdTuples(results)); ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, PQcmdStatus(results)); break; case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, PQerrorMessage(stmt->connection->connection)); register_error(ECPG_PGSQL, "Postgres error: %s line %d.", PQerrorMessage(stmt->connection->connection), stmt->lineno); status = false; break; case PGRES_COPY_OUT: ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno); PQendcopy(stmt->connection->connection); break; case PGRES_COPY_IN: ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno); PQendcopy(stmt->connection->connection); break; default: ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n", stmt->lineno); register_error(ECPG_PGSQL, "Postgres error: %s line %d.", PQerrorMessage(stmt->connection->connection), stmt->lineno); status = false; break; } PQclear(results); } /* check for asynchronous returns */ notify = PQnotifies(stmt->connection->connection); if (notify) { ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", stmt->lineno, notify->relname, notify->be_pid); free(notify); } return status;}boolECPGdo(int lineno, const char *connection_name, char *query,...){ va_list args; struct statement *stmt; struct connection *con = get_connection(connection_name); bool status; if (con == NULL) { register_error(ECPG_NO_CONN, "No such connection %s in line %d.", connection_name ? connection_name : "NULL", lineno); return (false); } va_start(args, query); if (create_statement(lineno, con, &stmt, query, args) == false) return (false); va_end(args); /* are we connected? */ if (con == NULL || con->connection == NULL) { ECPGlog("ECPGdo: not connected to %s\n", con->name); register_error(ECPG_NOT_CONN, "Not connected in line %d.", lineno); return false; } status = ECPGexecute(stmt); free_statement(stmt); return (status);}boolECPGstatus(int lineno, const char *connection_name){ struct connection *con = get_connection(connection_name); if (con == NULL) { register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return (false); } /* are we connected? */ if (con->connection == NULL) { ECPGlog("ECPGdo: not connected to %s\n", con->name); register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno); return false; } return (true);}boolECPGtrans(int lineno, const char *connection_name, const char *transaction){ PGresult *res; struct connection *con = get_connection(connection_name); if (con == NULL) { register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return (false); } ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name); /* if we have no connection we just simulate the command */ if (con && con->connection) { if ((res = PQexec(con->connection, transaction)) == NULL) { register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno); return FALSE; } PQclear(res); } if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0) { struct prepared_statement *this; con->committed = true; /* deallocate all prepared statements */ for (this = prep_stmts; this != NULL; this = this->next) { bool b = ECPGdeallocate(lineno, this->name); if (!b) return false; } } return true;}boolECPGsetcommit(int lineno, const char *mode, const char *connection_name){ struct connection *con = get_connection(connection_name); PGresult *results; if (con) { if (con->autocommit == true && strncmp(mode, "OFF", strlen("OFF")) == 0) { if (con->committed) { if ((results = PQexec(con->connection, "begin transaction")) == NULL) { register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno); return false; } PQclear(results); con->committed = false; } con->autocommit = false; } else if (con->autocommit == false && strncmp(mode, "ON", strlen("ON")) == 0) { if (!con->committed) { if ((results = PQexec(con->connection, "commit")) == NULL) { register_error(ECPG_TRANS, "Error in transaction processing line %d.", lineno); return false; } PQclear(results); con->committed = true; } con->autocommit = true; } } else { register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return false; } return true;}boolECPGsetconn(int lineno, const char *connection_name){ struct connection *con = get_connection(connection_name); if (con) { actual_connection = con; return true; } else { register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return false; }}boolECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name, int autocommit){ struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno); if (!this) return false; if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; /* add connection to our list */ if (connection_name != NULL) this->name = ecpg_strdup(connection_name, lineno); else this->name = ecpg_strdup(dbname, lineno); if (all_connections == NULL) this->next = NULL; else this->next = all_connections; actual_connection = all_connections = this; ECPGlog("ECPGconnect: opening database %s %s%s\n", dbname ? dbname : "<DEFAULT>", user ? "for user " : "", user ? user : ""); sqlca.sqlcode = 0; this->connection = PQsetdbLogin(NULL, NULL, NULL, NULL, dbname, user, passwd); if (PQstatus(this->connection) == CONNECTION_BAD) { ECPGfinish(this); ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "<DEFAULT>", user ? "for user " : "", user ? user : "", lineno); register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "<DEFAULT>"); return false; } this->committed = true; this->autocommit = autocommit; return true;}boolECPGdisconnect(int lineno, const char *connection_name){ struct connection *con; if (strcmp(connection_name, "ALL") == 0) { for (con = all_connections; con;) { struct connection *f = con; con = con->next; ECPGfinish(f); } } else { con = get_connection(connection_name); if (con == NULL) { ECPGlog("disconnect: not connected to connection %s\n", connection_name ? connection_name : "NULL"); register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name ? connection_name : "NULL", lineno); return false; } else ECPGfinish(con); } return true;}voidECPGdebug(int n, FILE *dbgs){ simple_debug = n; debugstream = dbgs; ECPGlog("ECPGdebug: set to %d\n", simple_debug);}voidECPGlog(const char *format,...){ va_list ap; if (simple_debug) { char *f = (char *) malloc(strlen(format) + 100); if (!f) return; sprintf(f, "[%d]: %s", (int) getpid(), format); va_start(ap, format); vfprintf(debugstream, f, ap); va_end(ap); free(f); }}/* print out an error message */voidsqlprint(void){ sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);}static boolisvarchar(unsigned char c){ if (isalnum(c)) return true; if (c == '_' || c == '>' || c == '-' || c == '.') return true; if (c >= 128) return true; return (false);}static voidreplace_variables(char *text){ char *ptr = text; bool string = false; for (; *ptr != '\0'; ptr++) { if (*ptr == '\'') string = string ? false : true; if (!string && *ptr == ':') { *ptr = '?'; for (++ptr; *ptr && isvarchar(*ptr); ptr++) *ptr = ' '; } }}/* handle the EXEC SQL PREPARE statement */boolECPGprepare(int lineno, char *name, char *variable){ struct statement *stmt; struct prepared_statement *this; /* check if we already have prepared this statement */ for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next); if (this) { bool b = ECPGdeallocate(lineno, name); if (!b) return false; } this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno); if (!this) return false; stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno); if (!stmt) { free(this); return false; } /* create statement */ stmt->lineno = lineno; stmt->connection = NULL; stmt->command = ecpg_strdup(variable, lineno); stmt->inlist = stmt->outlist = NULL; /* if we have C variables in our statment replace them with '?' */ replace_variables(stmt->command); /* add prepared statement to our list */ this->name = ecpg_strdup(name, lineno); this->stmt = stmt; if (prep_stmts == NULL) this->next = NULL; else this->next = prep_stmts; prep_stmts = this; return true;}/* handle the EXEC SQL DEALLOCATE PREPARE statement */boolECPGdeallocate(int lineno, char *name){ struct prepared_statement *this, *prev; /* check if we really have prepared this statement */ for (this = prep_stmts, prev = NULL; this != NULL && strcmp(this->name, name) != 0; prev = this, this = this->next); if (this) { /* okay, free all the resources */ free(this->name); free(this->stmt->command); free(this->stmt); if (prev != NULL) prev->next = this->next; else prep_stmts = this->next; return true; } ECPGlog("deallocate_prepare: invalid statement name %s\n", name); register_error(ECPG_INVALID_STMT, "Invalid statement name %s in line %d", name, lineno); return false;}/* return the prepared statement */char *ECPGprepared_statement(char *name){ struct prepared_statement *this; for (this = prep_stmts; this != NULL && strcmp(this->name, name) != 0; this = this->next); return (this) ? this->stmt->command : NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -