Пример #1
0
int main()
{
	int rc = 0;

	// set default password if none specified in environment
	setenv("ISC_USER", "sysdba", 0);
	setenv("ISC_PASSWORD", "masterkey", 0);

	// status vector and main dispatcher
	ThrowStatusWrapper status(master->getStatus());
	IProvider* prov = master->getDispatcher();

	// declare pointers to required interfaces
	IAttachment* att = NULL;
	ITransaction* tra = NULL;

	// Interface executes prepared SQL statement
	IStatement* stmt = NULL;

	// Interfaces provides access to format of data in messages
	IMessageMetadata* meta = NULL;

	// Interface makes it possible to change format of data or define it yourself
	IMetadataBuilder* builder = NULL;

	const char* updstr =
	    "UPDATE department SET budget = ? * budget + budget WHERE dept_no = ?";

	try
	{
		// attach employee db
		att = prov->attachDatabase(&status, "employee", 0, NULL);

		// start transaction
		tra = att->startTransaction(&status, 0, NULL);

		// prepare statement
		stmt = att->prepare(&status, tra, 0, updstr, SAMPLES_DIALECT, 0);

		// build metadata
		// IMaster creates empty new metadata in builder
		builder = master->getMetadataBuilder(&status, 2);
		// set required info on fields
		builder->setType(&status, 0, SQL_DOUBLE + 1);
		builder->setType(&status, 1, SQL_TEXT + 1);
		builder->setLength(&status, 1, 3);
		// IMetadata should be ready
		meta = builder->getMetadata(&status);
		// no need in builder any more
		builder->release();
		builder = NULL;

		// allocate buffer on stack
		char buffer[256];
		unsigned len = meta->getMessageLength(&status);
		if (len > sizeof(buffer))
		{
			throw "Input message length too big - can't continue";
		}

		// locations of parameters in input message
		char* dept_no = &buffer[meta->getOffset(&status, 1)];
 		double* percent_inc = (double*) &buffer[meta->getOffset(&status, 0)];

		// null IDs (set to NOT NULL)
 		short* flag = (short*)&buffer[meta->getNullOffset(&status, 0)];
 		*flag = 0;
 		flag = (short*) &buffer[meta->getNullOffset(&status, 1)];
 		*flag = 0;

		// Get the next department-percent increase input pair.
	    while (get_input(dept_no, percent_inc))
    	{
	        printf("\nIncreasing budget for department:  %s  by %5.2lf percent.\n",
    	           dept_no, *percent_inc);

			// Update the budget.
			try
			{
			    stmt->execute(&status, tra, meta, buffer, NULL, NULL);
			}
			catch (const FbException& error)
			{
				// Handle exception raised during statement execution
				if (error.getStatus()->getErrors()[1] == isc_not_valid)
				{
					// Don't save the update, if the new budget exceeds the limit.
					printf("\tExceeded budget limit -- not updated.\n");

					tra->rollbackRetaining(&status);
					continue;
				}

				// Another error - use default handler
				throw;
			}

			// Save each department's update independently.
			// *** Change to commitRetaining() to see changes
			// *** tra->commitRetaining(&status);
			tra->rollbackRetaining(&status);
        }

		// close interfaces
		stmt->free(&status);
		stmt = NULL;

		meta->release();
		meta = NULL;

		tra->commit(&status);
		tra = NULL;

		att->detach(&status);
		att = NULL;
	}
	catch (const FbException& error)
	{
		// handle error
		rc = 1;

		char buf[256];
		master->getUtilInterface()->formatStatus(buf, sizeof(buf), error.getStatus());
		fprintf(stderr, "%s\n", buf);
	}

	// release interfaces after error caught
	if (builder)
		builder->release();
	if (meta)
		meta->release();
	if (stmt)
		stmt->release();
	if (tra)
		tra->release();
	if (att)
		att->release();

	prov->release();
	status.dispose();

	return rc;
}
Пример #2
0
int main()
{
	int rc = 0;

	// set default password if none specified in environment
	setenv("ISC_USER", "sysdba", 0);
	setenv("ISC_PASSWORD", "masterkey", 0);

	// declare pointers to required interfaces
	IStatus* st = NULL;
	IProvider* prov = NULL;
	IAttachment* att = NULL;
	ITransaction* tra = NULL;

	// Interface executes prepared SQL statement
	IStatement* stmt = NULL;

	// Interfaces provides access to format of data in messages
	IMessageMetadata* meta = NULL;

	// Interface makes it possible to change format of data or define it yourself
	IMetadataBuilder* builder = NULL;

	const char* updstr =
	    "UPDATE department SET budget = ? * budget + budget WHERE dept_no = ?";

	try
	{
		// status vector and main dispatcher
		st = master->getStatus();
		prov = master->getDispatcher();

		// attach employee db
		att = prov->attachDatabase(st, "employee", 0, NULL);
		check(st, "attachDatabase");

		// start transaction
		tra = att->startTransaction(st, 0, NULL);
		check(st, "startTransaction");

		// prepare statement
		stmt = att->prepare(st, tra, 0, updstr, 3, 0);
		check(st, "prepare");

		// build metadata
		// IMaster creates empty new metadata in builder
		builder = master->getMetadataBuilder(st, 2);
		check(st, "getMetadataBuilder");
		// set required info on fields
		builder->setType(st, 0, SQL_DOUBLE + 1);
		check(st, "setType");
		builder->setType(st, 1, SQL_TEXT + 1);
		check(st, "setType");
		builder->setLength(st, 1, 3);
		check(st, "setLength");
		// IMetadata should be ready
		meta = builder->getMetadata(st);
		check(st, "getMetadata");
		// no need in builder any more
		builder->release();
		builder = NULL;

		// allocate buffer
		char buffer[256];
		unsigned len = meta->getMessageLength(st);
		check(st, "getMessageLength");
		if (len > 256)
		{
			throw "Input message length too big - can't continue";
		}

		// locations of parameters in input message
		char* dept_no = &buffer[meta->getOffset(st, 1)];
		check(st, "getOffset");
 		double* percent_inc = (double*) &buffer[meta->getOffset(st, 0)];
		check(st, "getOffset");

		// null IDs (set to NOT NULL)
 		short* flag = (short*)&buffer[meta->getNullOffset(st, 0)];
		check(st, "getNullOffset");
 		*flag = 0;
 		flag = (short*) &buffer[meta->getNullOffset(st, 1)];
		check(st, "getNullOffset");
 		*flag = 0;

		// Get the next department-percent increase input pair.
	    while (get_input(dept_no, percent_inc))
    	{
	        printf("\nIncreasing budget for department:  %s  by %5.2lf percent.\n",
    	           dept_no, *percent_inc);

			// Update the budget.
	        stmt->execute(st, tra, meta, buffer, NULL, NULL);
	        if (st->getStatus() & IStatus::FB_HAS_ERRORS)
    	    {
		        int sqlcode = isc_sqlcode(st->getErrors());
    	        // Don't save the update, if the new budget exceeds the limit.
        	    if (sqlcode == -625)
            	{
	                printf("\tExceeded budget limit -- not updated.\n");

    	            tra->rollbackRetaining(st);
    	            check(st, "rollback");
	                continue;
    	        }

    	        // use default handler
    	        check(st, "execute");
            }

			// Save each department's update independently.
			// *** Change to commitRetaining() to see changes
			// *** tra->commitRetaining(st);
			tra->rollbackRetaining(st);
			check(st, "rollback");
        }

		// close interfaces
		stmt->free(st);
		check(st, "free");
		stmt = NULL;

		meta->release();
		meta = NULL;

		tra->commit(st);
		check(st, "commit");
		tra = NULL;

		att->detach(st);
		check(st, "detach");
		att = NULL;
	}
	catch (const char* text)
	{
		// handle error
		rc = 1;
		fprintf(stderr, "%s:\n", text);
		if (st)
			isc_print_status(st->getErrors());
	}

	// release interfaces after error caught
	if (builder)
		builder->release();
	if (meta)
		meta->release();
	if (stmt)
		stmt->release();
	if (tra)
		tra->release();
	if (att)
		att->release();
	if (prov)
		prov->release();
	if (st)
		st->dispose();

	return rc;
}