Beispiel #1
0
/*{
** Name:	RSdtrans_id_register - register distributed transaction ID
**
** Description:
**	Register a distributed transaction ID.
**
** Inputs:
**	none
**
** Outputs:
**	none
**
** Returns:
**	OK or FAIL
*/
STATUS
RSdtrans_id_register(
RS_TARGET	*target)
{
	RS_CONN			*conn = &RSlocal_conn;
	IIAPI_DATAVALUE		cdata;
	II_PTR			stmtHandle;
	IIAPI_GETEINFOPARM	errParm;
	IIAPI_STATUS		status;
	IIAPI_GETQINFOPARM	getQinfoParm;

	if (first || low == high_limit)
	{
		status = IIsw_query(conn->connHandle, &conn->tranHandle,
			ERx("UPDATE dd_last_number SET last_number = \
last_number + 100 WHERE column_name = 'next_transaction_id'"),
			0, NULL, NULL, NULL, NULL, &stmtHandle, &getQinfoParm,
			&errParm);
		if (RSerror_check(1234, ROWS_SINGLE_ROW, stmtHandle, 
			 &getQinfoParm, &errParm, NULL) != OK)
		{
			IIsw_rollback(&conn->tranHandle, &errParm);
			return (FAIL);
		}

		SW_COLDATA_INIT(cdata, high_limit);
		status = IIsw_selectSingleton(conn->connHandle,
			&conn->tranHandle,
			ERx("SELECT last_number FROM dd_last_number WHERE \
column_name = 'next_transaction_id'"),
			0, NULL, NULL, 1, &cdata, NULL, NULL, &stmtHandle,
			 &getQinfoParm, &errParm);
		if (RSerror_check(1234, ROWS_SINGLE_ROW, stmtHandle, 
			 &getQinfoParm, &errParm, NULL) != OK)
		{
			IIsw_rollback(&conn->tranHandle, &errParm);
			return (FAIL);
		}
		first = FALSE;
		low = high_limit - 100;
	}
Beispiel #2
0
/*{
** Name:	RSdelete	- propagate a DELETE row
**
** Description:
**	Propagates a DELETE transaction row, either by calling a remote
**	database procedure or by executing a remote DELETE.
**
** Inputs:
**	row		- row of data
**
** Outputs:
**	none
**
** Returns:
**	OK
**	else	- error
*/
STATUS
RSdelete(
RS_TARGET	*target,
RS_TRANS_ROW	*row)
{
	char 			*stmt=NULL;
	char			*proc_name;
	STATUS			err;
	bool			collision_processed = FALSE;
	RS_TBLDESC		*tbl = row->tbl_desc;
	II_INT2			nparams;
	IIAPI_DESCRIPTOR	pdesc[DB_MAX_COLS+1];
	IIAPI_DATAVALUE		pdata[DB_MAX_COLS+1];
	DB_DELIM_STR		*pnames = NULL;
	RS_CONN			*conn = &RSconns[target->conn_no];
	II_LONG			procRet;
	II_PTR			stmtHandle;
	IIAPI_GETEINFOPARM	errParm;
	IIAPI_GETQINFOPARM	getQinfoParm;
	IIAPI_STATUS		status;
	IIAPI_DESCRIPTOR 	*col;
	IIAPI_DESCRIPTOR 	*pds;
	i4			num_cols=tbl->num_regist_cols;
	i4			row_width=tbl->row_width;

	stmt = RSmem_allocate(row_width,num_cols,DB_MAXNAME+8,128); 
	if (stmt == NULL)
	   return (FAIL);

	messageit(5, 1268, row->rep_key.src_db, row->rep_key.trans_id,
		row->rep_key.seq_no, target->db_no);

	err = RScollision(target, row, tbl, &collision_processed);
	if (err || collision_processed)
	{
		MEfree((PTR)stmt);
		return (err);
	}

	/* For URO targets, delete the base row. */
	if (target->type == TARG_UNPROT_READ)
	{
		char	*where_list=NULL;
		char	objname[DB_MAXNAME*2+3];

		where_list = RSmem_allocate(row_width,tbl->num_key_cols,DB_MAXNAME+8,0); 
		if (where_list == NULL)
		{
			MEfree((PTR)stmt);
			return (FAIL);
		}
		/*
		** Iterate through key_desc and create the WHERE list and
		** prepare the column descriptors. The data will come directly
		** from key_data.
		*/
		*where_list = EOS;
		for (col = row->key_desc, pds = pdesc;
			col < row->key_desc + tbl->num_key_cols; ++col, ++pds)
		{
			if (col != row->key_desc)
				STcat(where_list, ERx(" AND "));
			/*
			** The following is special case code to allow existing
			** customers in non-SQL92 installations to propagate to
			** Gateway databases that use uppercase table and
			** column names.
			*/
			if (conn->name_case == UI_UPPERCASE)
			{
				STcopy(col->ds_columnName, objname);
				CVupper(objname);
				STcat(where_list, objname);
			}
			else
			{
				STcat(where_list, col->ds_columnName);
			}
			STcat(where_list, ERx(" = ~V"));
			*pds = *col;	/* struct */
			pds->ds_columnType = IIAPI_COL_QPARM;
		}
		STcopy(tbl->dlm_table_name, objname);
		if (target->type == TARG_UNPROT_READ &&
				conn->name_case == UI_UPPERCASE)
			CVupper(objname);
		STprintf(stmt, ERx("DELETE FROM %s.%s WHERE %s"),
			tbl->rem_table_owner, objname, where_list);
		status = IIsw_query(conn->connHandle, &conn->tranHandle, stmt,
			tbl->num_key_cols, pdesc, row->key_data, NULL, NULL,
			&stmtHandle, &getQinfoParm, &errParm);
		status = RSerror_check(1556, ROWS_SINGLE_ROW, stmtHandle,
			&getQinfoParm, &errParm, NULL, tbl->table_name);
		MEfree((PTR)where_list);
		if (status != OK)
		{
			MEfree((PTR)stmt);
			return (status);
		}
	}
	/* For FP and PRO targets, call the remote database procedure. */
	else
	{
	      pnames = (DB_DELIM_STR *)RSmem_allocate(0, DB_MAX_COLS+1,
			sizeof(*pnames),0); 
	      if (pnames == NULL)
	      {
		 MEfree((PTR)stmt);
		 return (FAIL);
	      }

		proc_name = pnames[0];
		if (RPtblobj_name(tbl->table_name, row->table_no,
			TBLOBJ_REM_DEL_PROC, proc_name) != OK)
		{
			messageit(1, 1816, ERx("RSdelete"), tbl->table_name);
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (RS_INTERNAL_ERR);
		}

		if (RSpdp_PrepDbprocParams(proc_name, target, tbl, row, pnames,
				&nparams, pdesc, pdata) != OK)
		{
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (RS_INTERNAL_ERR);
		}
		status = IIsw_execProcedure(conn->connHandle,
			&conn->tranHandle, nparams, pdesc, pdata, &procRet,
			&stmtHandle, &getQinfoParm, &errParm);
		status = RSerror_check(1573, ROWS_DONT_CARE, stmtHandle,
			&getQinfoParm, &errParm, NULL, proc_name);
		if (status != OK)
		{
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (status);
		}
		if (procRet)
		{
			messageit(1, procRet, row->rep_key.src_db,
				row->rep_key.trans_id, row->rep_key.seq_no,
				target->db_no, tbl->table_name);
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (procRet);
		}
	}

	RSstats_update(target->db_no, tbl->table_no, RS_DELETE);
	if (target->type != TARG_UNPROT_READ)
		RSmonitor_notify(&RSconns[target->conn_no], RS_INC_DELETE,
			RSlocal_conn.db_no, tbl->table_name, tbl->table_owner);
	RSmonitor_notify(&RSlocal_conn, RS_OUT_DELETE, target->db_no,
		tbl->table_name, tbl->table_owner);

	RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
	return (OK);
}