예제 #1
0
파일: km_dbase.c 프로젝트: kiryu/kamailio
/**
 * Ends a transaction and rollsback the changes (SQL ROLLBACK)
 * \param _h database handle
 * \return 1 if there was something to rollback, 0 if not, negative on failure
 */
int db_postgres_abort_transaction(db1_con_t* _h)
{
	db1_res_t *res = NULL;
	str query_str = str_init("ROLLBACK");
	
	if (!_h) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	if (CON_TRANSACTION(_h) == 0) {
		LM_DBG("nothing to rollback\n");
		return 0;
	}

	/* Whether the rollback succeeds or not we need to _end_ the
 	   transaction now or all future starts will fail */
	CON_TRANSACTION(_h) = 0;

	if (db_postgres_raw_query(_h, &query_str, &res) < 0)
	{
		LM_ERR("executing raw_query\n");
		return -1;
	}

	if (res) db_postgres_free_result(_h, res);

	return 1;
}
예제 #2
0
파일: km_dbase.c 프로젝트: kiryu/kamailio
/**
 * Starts a single transaction that will consist of one or more queries (SQL BEGIN)
 * \param _h database handle
 * \return 0 on success, negative on failure
 */
int db_postgres_start_transaction(db1_con_t* _h)
{
	db1_res_t *res = NULL;
	str query_str = str_init("BEGIN");
	
	if (!_h) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	if (CON_TRANSACTION(_h) == 1) {
		LM_ERR("transaction already started\n");
		return -1;
	}

	if (db_postgres_raw_query(_h, &query_str, &res) < 0)
	{
		LM_ERR("executing raw_query\n");
		return -1;
	}

	if (res) db_postgres_free_result(_h, res);

	CON_TRANSACTION(_h) = 1;
	return 0;
}
예제 #3
0
파일: km_dbase.c 프로젝트: kiryu/kamailio
/**
 * Ends a transaction and commits the changes (SQL COMMIT)
 * \param _h database handle
 * \return 0 on success, negative on failure
 */
int db_postgres_end_transaction(db1_con_t* _h)
{
	db1_res_t *res = NULL;
	str query_str = str_init("COMMIT");
	
	if (!_h) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	if (CON_TRANSACTION(_h) == 0) {
		LM_ERR("transaction not in progress\n");
		return -1;
	}

	if (db_postgres_raw_query(_h, &query_str, &res) < 0)
	{
		LM_ERR("executing raw_query\n");
		return -1;
	}

	if (res) db_postgres_free_result(_h, res);

	/* Only _end_ the transaction after the raw_query.  That way, if the
 	   raw_query fails, and the calling module does an abort_transaction()
	   to clean-up, a ROLLBACK will be sent to the DB. */
	CON_TRANSACTION(_h) = 0;
	return 0;
}
예제 #4
0
/**
 * Starts a single transaction that will consist of one or more queries (SQL BEGIN)
 * \param _h database handle
 * \return 0 on success, negative on failure
 */
int db_postgres_start_transaction(db1_con_t* _h, db_locking_t _l)
{
	db1_res_t *res = NULL;
	str begin_str = str_init("BEGIN");
	str lock_start_str = str_init("LOCK TABLE ");
	str lock_write_end_str = str_init(" IN EXCLUSIVE MODE");
	str lock_full_end_str = str_init(" IN ACCESS EXCLUSIVE MODE");
	str *lock_end_str = &lock_write_end_str;
	str lock_str = {0, 0};
	
	if (!_h) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	if (CON_TRANSACTION(_h) == 1) {
		LM_ERR("transaction already started\n");
		return -1;
	}

	if (db_postgres_raw_query(_h, &begin_str, &res) < 0)
	{
		LM_ERR("executing raw_query\n");
		return -1;
	}

	if (res) db_postgres_free_result(_h, res);

	CON_TRANSACTION(_h) = 1;

	switch(_l)
	{
	case DB_LOCKING_NONE:
		break;
	case DB_LOCKING_FULL:
		lock_end_str = &lock_full_end_str;
		/* Fall-thru */
	case DB_LOCKING_WRITE:
		if ((lock_str.s = pkg_malloc((lock_start_str.len + CON_TABLE(_h)->len + lock_end_str->len) * sizeof(char))) == NULL)
		{
			LM_ERR("allocating pkg memory\n");
			goto error;
		}

		memcpy(lock_str.s, lock_start_str.s, lock_start_str.len);
		lock_str.len += lock_start_str.len;
		memcpy(lock_str.s + lock_str.len, CON_TABLE(_h)->s, CON_TABLE(_h)->len);
		lock_str.len += CON_TABLE(_h)->len;
		memcpy(lock_str.s + lock_str.len, lock_end_str->s, lock_end_str->len);
		lock_str.len += lock_end_str->len;

		if (db_postgres_raw_query(_h, &lock_str, &res) < 0)
		{
			LM_ERR("executing raw_query\n");
			goto error;
		}

		if (res) db_postgres_free_result(_h, res);
		if (lock_str.s) pkg_free(lock_str.s);
		break;

	default:
		LM_WARN("unrecognised lock type\n");
		goto error;
	}

	return 0;

error:
	if (lock_str.s) pkg_free(lock_str.s);
	db_postgres_abort_transaction(_h);
	return -1;
}