예제 #1
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_base(switch_pgsql_handle_t *handle, const char *sql, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
	char *err_str = NULL;

	handle->affected_rows = 0;

	if (!db_is_up(handle)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not up!\n");
		goto error;
	}

	if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) {
		if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) {
			switch_pgsql_finish_results(handle);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n");
			goto error;
		}

		if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending BEGIN!\n");
			goto error;
		}
		handle->in_txn = SWITCH_TRUE;
	}

	if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) {
		switch_pgsql_finish_results(handle);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending query!\n");
		goto error;
	}

	return SWITCH_PGSQL_SUCCESS;

  error:
	err_str = switch_pgsql_handle_get_error(handle);

	if (zstr(err_str)) {
		err_str = strdup((char *)"SQL ERROR!");
	}
	
	if (err_str) {
		if (!switch_stristr("already exists", err_str) && !switch_stristr("duplicate key name", err_str)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
		}
		if (err) {
			*err = err_str;
		} else {
			free(err_str);
		}
	}
#endif
	return SWITCH_PGSQL_FAIL;
}
예제 #2
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line,
        switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
    switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS;
    char *val = NULL;
    switch_pgsql_result_t *result = NULL;

    handle->affected_rows = 0;

    if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) {
        goto error;
    }

    if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
        goto error;
    }

    if (result) {
        switch (result->status) {
#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2
        case PGRES_SINGLE_TUPLE:
            /* Added in PostgreSQL 9.2 */
#endif
        case PGRES_COMMAND_OK:
        case PGRES_TUPLES_OK:
            break;
        default:
            sstatus = SWITCH_PGSQL_FAIL;
            goto done;
        }
    }

    if (handle->affected_rows <= 0) {
        goto done;
    }

    val = PQgetvalue(result->result, 0, 0);
    strncpy(resbuf, val, len);

done:

    switch_pgsql_free_result(&result);
    if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
        sstatus = SWITCH_PGSQL_FAIL;
    }

    return sstatus;
error:
    return SWITCH_PGSQL_FAIL;
#else
    return SWITCH_PGSQL_FAIL;
#endif
}
예제 #3
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec(switch_pgsql_handle_t *handle, const char *sql, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
	if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
		goto error;
	}

	return switch_pgsql_finish_results(handle);
  error:
#endif
	return SWITCH_PGSQL_FAIL;
}
예제 #4
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char* sql)
{
#ifdef SWITCH_HAVE_PGSQL
	char *err_str;

	if (!PQsendQuery(handle->con, sql)) {
		err_str = switch_pgsql_handle_get_error(handle);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
		switch_pgsql_finish_results(handle);
		goto error;
	}
	handle->sql = sql;

	return SWITCH_PGSQL_SUCCESS;
 error:
#endif
	return SWITCH_PGSQL_FAIL;
}
예제 #5
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err)
{
#ifdef SWITCH_HAVE_PGSQL
	switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS;
	char *val = NULL;
	switch_pgsql_result_t *result = NULL;

	handle->affected_rows = 0;

	if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
		goto error;
	}

	if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
		goto error;
	}

	if (!result || result->status != PGRES_COMMAND_OK) {
		sstatus = SWITCH_PGSQL_FAIL;
		goto done;
	}

	if (handle->affected_rows <= 0) {
		goto done;
	}

	val = PQgetvalue(result->result, 0, 0);
	strncpy(resbuf, val, len);

	done:

	switch_pgsql_free_result(&result);
	if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) {
		sstatus = SWITCH_PGSQL_FAIL;
	}

	return sstatus;
 error:
	return SWITCH_PGSQL_FAIL;
#else
	return SWITCH_PGSQL_FAIL;
#endif
}
예제 #6
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed(const char *file, const char *func, int line,
        switch_pgsql_handle_t *handle,
        const char *sql, switch_core_db_callback_func_t callback, void *pdata,
        char **err)
{
#ifdef SWITCH_HAVE_PGSQL
    char *err_str = NULL;
    int row = 0, col = 0, err_cnt = 0;
    switch_pgsql_result_t *result = NULL;

    handle->affected_rows = 0;

    switch_assert(callback != NULL);

    if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
        goto error;
    }

    if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
        err_cnt++;
        err_str = switch_pgsql_handle_get_error(handle);
        if (result && !zstr(result->err)) {
            switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err));
        }
        if (!zstr(err_str)) {
            switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
        }
        switch_safe_free(err_str);
        err_str = NULL;
    }

    while (result != NULL) {
        /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result with %d rows and %d columns.\n", result->rows, result->cols);*/
        for (row = 0; row < result->rows; ++row) {
            char **names;
            char **vals;

            names = calloc(result->cols, sizeof(*names));
            vals = calloc(result->cols, sizeof(*vals));

            switch_assert(names && vals);

            for (col = 0; col < result->cols; ++col) {
                char * tmp;
                int len;

                tmp = PQfname(result->result, col);
                if (tmp) {
                    len = strlen(tmp);
                    names[col] = malloc(len+1);
                    names[col][len] = '\0';
                    strncpy(names[col], tmp, len);

                    len = PQgetlength(result->result, row, col);
                    vals[col] = malloc(len+1);
                    vals[col][len] = '\0';
                    tmp = PQgetvalue(result->result, row, col);
                    strncpy(vals[col], tmp, len);
                    /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d: %s => %s\n", row, col, names[col], vals[col]);*/
                } else {
                    /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d.\n", row, col);*/
                    switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: Column number %d out of range\n", col);
                }
            }

            /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing callback for row %d...\n", row);*/
            if (callback(pdata, result->cols, vals, names)) {
                switch_pgsql_finish_results(handle); /* Makes sure next call to switch_pgsql_next_result will return NULL */
                row = result->rows;                  /* Makes us exit the for loop */
            }

            for (col = 0; col < result->cols; ++col) {
                free(names[col]);
                free(vals[col]);
            }
            free(names);
            free(vals);
        }
        switch_pgsql_free_result(&result);
        if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
            err_cnt++;
            err_str = switch_pgsql_handle_get_error(handle);
            if (result && !zstr(result->err)) {
                switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err));
            }
            if (!zstr(err_str)) {
                switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
            }
            switch_safe_free(err_str);
            err_str = NULL;
        }
    }
    if (err_cnt) {
        goto error;
    }

    return SWITCH_PGSQL_SUCCESS;
error:
#endif
    return SWITCH_PGSQL_FAIL;
}