16.patch
text/x-patch
Filename: 16.patch
Type: text/x-patch
Part: 7
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/interfaces/ecpg/ecpglib/execute.c | 77 | 12 |
| src/interfaces/ecpg/ecpglib/extern.h | 5 | 1 |
commit 0ee438401c8e339912cc693ed9f140ad8c13bd95
Author: Böszörményi Zoltán <zb@cybertec.at>
Date: Wed Dec 4 14:14:46 2013 +0100
ECPG: Split ecpg_execute() up into 4 pieces: ecpg_build_params(),
ecpg_autostart_transaction(), a smaller ecpg_execute() and
ecpg_process_output().
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e3a44f7..00327db 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1125,17 +1125,17 @@ insert_tobeinserted(int position, int ph_len, struct statement * stmt, char *tob
return true;
}
-static bool
-ecpg_execute(struct statement * stmt)
+/*
+ * ecpg_build_params
+ * Build statement parameters from user variables into
+ * an array of strings for PQexecParams().
+ */
+bool
+ecpg_build_params(struct statement * stmt)
{
- bool status = false;
- char *cmdstat;
- PGnotify *notify;
struct variable *var;
int desc_counter = 0;
int position = 0;
- struct sqlca_t *sqlca = ECPGget_sqlca();
- bool clear_result = true;
/*
* If the type is one of the fill in types then we take the argument and
@@ -1421,8 +1421,17 @@ ecpg_execute(struct statement * stmt)
return false;
}
- /* The request has been build. */
+ return true;
+}
+/*
+ * ecpg_autostart_transaction
+ * If we are in non-autocommit mode, automatically start
+ * a transaction.
+ */
+bool
+ecpg_autostart_transaction(struct statement * stmt)
+{
if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
{
stmt->results = PQexec(stmt->connection->connection, "begin transaction");
@@ -1434,7 +1443,16 @@ ecpg_execute(struct statement * stmt)
PQclear(stmt->results);
stmt->results = NULL;
}
+ return true;
+}
+/*
+ * ecpg_execute
+ * Execute the SQL statement.
+ */
+bool
+ecpg_execute(struct statement * stmt)
+{
ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
if (stmt->statement_type == ECPGst_execute)
{
@@ -1460,6 +1478,33 @@ ecpg_execute(struct statement * stmt)
if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
return (false);
+ return true;
+}
+
+/*
+ * ecpg_process_output
+ * Process the statement result and store it into application variables.
+ * This function can be called repeatedly during the same statement
+ * in case cursor readahed is used and the application does FETCH N which
+ * overflows the readahead window.
+ *
+ * Parameters
+ * stmt statement structure holding the PGresult and
+ * the list of output variables
+ * clear_result
+ * PQclear() the result upon returning from this function
+ *
+ * Returns success as boolean. Also an SQL error is raised in case of failure.
+ */
+bool
+ecpg_process_output(struct statement * stmt, bool clear_result)
+{
+ struct variable *var;
+ bool status = false;
+ char *cmdstat;
+ PGnotify *notify;
+ struct sqlca_t *sqlca = ECPGget_sqlca();
+
var = stmt->outlist;
switch (PQresultStatus(stmt->results))
{
@@ -1947,7 +1992,6 @@ bool
ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
{
struct statement *stmt;
- bool status;
if (!ecpg_do_prologue(lineno, compat, force_indicator,
connection_name, questionmarks,
@@ -1958,12 +2002,33 @@ ecpg_do(const int lineno, const int compat, const int force_indicator, const cha
return false;
}
- status = ecpg_execute(stmt);
+ if (!ecpg_build_params(stmt))
+ {
+ ecpg_do_epilogue(stmt);
+ return false;
+ }
+
+ if (!ecpg_autostart_transaction(stmt))
+ {
+ ecpg_do_epilogue(stmt);
+ return false;
+ }
+
+ if (!ecpg_execute(stmt))
+ {
+ ecpg_do_epilogue(stmt);
+ return false;
+ }
+
+ if (!ecpg_process_output(stmt, true))
+ {
+ ecpg_do_epilogue(stmt);
+ return false;
+ }
- /* and reset locale value so our application is not affected */
ecpg_do_epilogue(stmt);
- return (status);
+ return true;
}
/*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index 50fe87f..1f96869 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -169,10 +169,14 @@ bool ecpg_store_result(const PGresult *results, int act_field,
const struct statement * stmt, struct variable * var);
bool ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
void ecpg_free_params(struct statement *stmt, bool print);
-void ecpg_do_epilogue(struct statement *);
bool ecpg_do_prologue(int, const int, const int, const char *, const bool,
enum ECPG_statement_type, const char *, va_list,
struct statement **);
+bool ecpg_build_params(struct statement *);
+bool ecpg_autostart_transaction(struct statement * stmt);
+bool ecpg_execute(struct statement * stmt);
+bool ecpg_process_output(struct statement *, bool);
+void ecpg_do_epilogue(struct statement *);
bool ecpg_do(const int, const int, const int, const char *, const bool,
const int, const char *, va_list);