path = get_pool_memory(PM_FNAME);
esc_name = get_pool_memory(PM_FNAME);
esc_path = get_pool_memory(PM_FNAME);
+ esc_obj = get_pool_memory(PM_FNAME);
+ m_buf = get_pool_memory(PM_FNAME);
m_allow_transactions = mult_db_connections;
+ /* At this time, when mult_db_connections == true, this is for
+ * specific console command such as bvfs or batch mode, and we don't
+ * want to share a batch mode or bvfs. In the future, we can change
+ * the creation function to add this parameter.
+ */
+ m_dedicated = mult_db_connections;
+
/*
* Initialize the private members.
*/
}
sql_query("SET datestyle TO 'ISO, YMD'");
+ sql_query("SET cursor_tuple_fraction=1");
/*
* Tell PostgreSQL we are using standard conforming strings
{
db_end_transaction(jcr);
P(mutex);
- sql_free_result();
m_ref_count--;
if (m_ref_count == 0) {
+ sql_free_result();
db_list->remove(this);
if (m_connected && m_db_handle) {
PQfinish(m_db_handle);
free_pool_memory(path);
free_pool_memory(esc_name);
free_pool_memory(esc_path);
+ free_pool_memory(esc_obj);
+ free_pool_memory(m_buf);
if (m_db_driver) {
free(m_db_driver);
}
if (m_db_socket) {
free(m_db_socket);
}
- if (esc_obj) {
- PQfreemem(esc_obj);
- }
delete this;
if (db_list->size() == 0) {
delete db_list;
db_unlock(this);
}
+
+/*
+ * Submit a general SQL command (cmd), and for each row returned,
+ * the result_handler is called with the ctx.
+ */
+bool B_DB_POSTGRESQL::db_big_sql_query(const char *query,
+ DB_RESULT_HANDLER *result_handler,
+ void *ctx)
+{
+ SQL_ROW row;
+ bool retval = false;
+ bool in_transaction = m_transaction;
+
+ Dmsg1(500, "db_sql_query starts with '%s'\n", query);
+
+ /* This code handles only SELECT queries */
+ if (strncasecmp(query, "SELECT", 6) != 0) {
+ return db_sql_query(query, result_handler, ctx);
+ }
+
+ if (!result_handler) { /* no need of big_query without handler */
+ return false;
+ }
+
+ db_lock(this);
+
+ if (!in_transaction) { /* CURSOR needs transaction */
+ sql_query("BEGIN");
+ }
+
+ Mmsg(m_buf, "DECLARE _bac_cursor CURSOR FOR %s", query);
+
+ if (!sql_query(m_buf)) {
+ Mmsg(errmsg, _("Query failed: %s: ERR=%s\n"), m_buf, sql_strerror());
+ Dmsg0(50, "db_sql_query failed\n");
+ goto bail_out;
+ }
+
+ do {
+ if (!sql_query("FETCH 100 FROM _bac_cursor")) {
+ goto bail_out;
+ }
+ while ((row = sql_fetch_row()) != NULL) {
+ Dmsg1(500, "Fetching %d rows\n", m_num_rows);
+ if (result_handler(ctx, m_num_fields, row))
+ break;
+ }
+ PQclear(m_result);
+ m_result = NULL;
+
+ } while (m_num_rows > 0); /* TODO: Can probably test against 100 */
+
+ sql_query("CLOSE _bac_cursor");
+
+ Dmsg0(500, "db_big_sql_query finished\n");
+ sql_free_result();
+ retval = true;
+
+bail_out:
+ if (!in_transaction) {
+ sql_query("COMMIT"); /* end transaction */
+ }
+
+ db_unlock(this);
+ return retval;
+}
+
/*
* Submit a general SQL command (cmd), and for each row returned,
* the result_handler is called with the ctx.
Dmsg0(500, "sql_fetch_row start\n");
+ if (m_num_fields == 0) { /* No field, no row */
+ Dmsg0(500, "sql_fetch_row finishes returning NULL, no fields\n");
+ return NULL;
+ }
+
if (!m_rows || m_rows_size < m_num_fields) {
if (m_rows) {
Dmsg0(500, "sql_fetch_row freeing space\n");
Dmsg0(500, "sql_batch_start started\n");
if (!sql_query("CREATE TEMPORARY TABLE batch ("
- "fileindex int,"
- "jobid int,"
- "path varchar,"
- "name varchar,"
- "lstat varchar,"
- "md5 varchar,"
- "markid int)")) {
+ "FileIndex int,"
+ "JobId int,"
+ "Path varchar,"
+ "Name varchar,"
+ "LStat varchar,"
+ "Md5 varchar,"
+ "DeltaSeq smallint)")) {
Dmsg0(500, "sql_batch_start failed\n");
return false;
}