示例#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);

	// declare pointers to required interfaces
	IStatus* st = NULL;
	IProvider* prov = NULL;
	IAttachment* att = NULL;
	ITransaction* tra = NULL;
	IStatement* stmt = NULL;
	IResultSet* curs = NULL;
	IMessageMetadata* meta = NULL;
	IMetadataBuilder* builder = NULL;

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

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

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

		// prepare statement
		stmt = att->prepare(st, tra, 0, "select * from country", 3,
			IStatement::PREPARE_PREFETCH_METADATA);
		check(st, "prepare");

		// get list of columns
		meta = stmt->getOutputMetadata(st);
		check(st, "getOutputMetadata");
		builder = meta->getBuilder(st);
		check(st, "getBuilder");
		unsigned cols = meta->getCount(st);
		check(st, "getCount");

		// struct to cache received metadata
		struct MyField
		{
			const char* name;
			unsigned length, offset;
		};
		MyField* fields = new MyField[cols];
		memset(fields, 0, sizeof(MyField) * cols);

		// parse columns list & coerce datatype(s)
		for (unsigned j = 0; j < cols; ++j)
		{
			unsigned t = meta->getType(st, j);
			check(st, "getType");

			if (t == SQL_VARYING || t == SQL_TEXT)
			{
				builder->setType(st, j, SQL_TEXT);
				check(st, "setType");
				fields[j].name = meta->getField(st, j);
				check(st, "getField");
			}
		}

		meta->release();
		meta = builder->getMetadata(st);
		check(st, "getMetadata");

		// now we may also get offsets info
		for (unsigned j = 0; j < cols; ++j)
		{
			if (fields[j].name)
			{
				fields[j].length = meta->getLength(st, j);
				check(st, "getLength");
				fields[j].offset = meta->getOffset(st, j);
				check(st, "getOffset");
			}
		}

		builder->release();
		builder = NULL;

		// open cursor
		curs = stmt->openCursor(st, tra, NULL, NULL, meta);
		check(st, "openCursor");

		// allocate output buffer
		unsigned l = meta->getMessageLength(st);
		check(st, "getMessageLength");
		unsigned char* buffer = new unsigned char[l];

		// fetch records from cursor and print them
		while (curs->fetch(st, buffer))
		{
			for (unsigned j = 0; j < cols; ++j)
			{
				if (fields[j].name)
				{
					printf("%s: %*.*s\n", fields[j].name, fields[j].length, fields[j].length,
						buffer + fields[j].offset);
				}
			}
			printf("\n");
		}
		check(st, "fetch");

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

		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->get());
	}

	// release interfaces after error caught
	if (meta)
		meta->release();
	if (builder)
		builder->release();
	if (curs)
		curs->release();
	if (stmt)
		stmt->release();
	if (tra)
		tra->release();
	if (att)
		att->release();
	if (prov)
		prov->release();
	if (st)
		st->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);

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

	// declare pointers to required interfaces
	IAttachment* att = NULL;
	ITransaction* tra = NULL;
	IStatement* stmt = NULL;
	IMessageMetadata* meta = NULL;
	IMetadataBuilder* builder = NULL;
	IXpbBuilder* tpb = NULL;

	// Interface provides access to data returned by SELECT statement
	IResultSet* curs = NULL;

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

		// start read only transaction
		tpb = utl->getXpbBuilder(&status, IXpbBuilder::TPB, NULL, 0);
		tpb->insertTag(&status, isc_tpb_read_committed);
		tpb->insertTag(&status, isc_tpb_no_rec_version);
		tpb->insertTag(&status, isc_tpb_wait);
		tpb->insertTag(&status, isc_tpb_read);
		tra = att->startTransaction(&status, tpb->getBufferLength(&status), tpb->getBuffer(&status));

		// prepare statement
		stmt = att->prepare(&status, tra, 0, "select last_name, first_name, phone_ext from phone_list "
										"where location = 'Monterey' order by last_name, first_name",
			SAMPLES_DIALECT, IStatement::PREPARE_PREFETCH_METADATA);

		// get list of columns
		meta = stmt->getOutputMetadata(&status);
		builder = meta->getBuilder(&status);
		unsigned cols = meta->getCount(&status);

		// struct to cache received metadata
		struct MyField
		{
			const char* name;
			unsigned length, offset;
		};
		MyField* fields = new MyField[cols];
		memset(fields, 0, sizeof(MyField) * cols);

		// parse columns list & coerce datatype(s)
		for (unsigned j = 0; j < cols; ++j)
		{
			unsigned t = meta->getType(&status, j);

			if (t == SQL_VARYING || t == SQL_TEXT)
			{
				builder->setType(&status, j, SQL_TEXT);
				fields[j].name = meta->getField(&status, j);
			}
		}

		// release automatically created metadata
		// metadata is not database object, therefore no specific call to close it
		meta->release();

		// get metadata with coerced datatypes
		meta = builder->getMetadata(&status);

		// builder not needed any more
		builder->release();
		builder = NULL;

		// now we may also get offsets info
		for (unsigned j = 0; j < cols; ++j)
		{
			if (fields[j].name)
			{
				fields[j].length = meta->getLength(&status, j);
				fields[j].offset = meta->getOffset(&status, j);
			}
		}

		// open cursor
		curs = stmt->openCursor(&status, tra, NULL, NULL, meta, 0);

		// allocate output buffer
		unsigned l = meta->getMessageLength(&status);
		unsigned char* buffer = new unsigned char[l];

		// fetch records from cursor and print them
		for (int line = 0; curs->fetchNext(&status, buffer) == IStatus::RESULT_OK; ++line)
		{
			if (line % 10 == 0)
			{
				printf("\n");
				for (unsigned j = 0; j < cols; ++j)
				{
					if (fields[j].name)
					{
						printf("%-*.*s ", fields[j].length, fields[j].length, fields[j].name);
					}
				}
				printf("\n");
			}

			for (unsigned j = 0; j < cols; ++j)
			{
				if (fields[j].name)
				{
					printf("%*.*s ", fields[j].length, fields[j].length, buffer + fields[j].offset);
				}
			}
			printf("\n");
		}
		printf("\n");

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

		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 (meta)
		meta->release();
	if (builder)
		builder->release();
	if (curs)
		curs->release();
	if (stmt)
		stmt->release();
	if (tra)
		tra->release();
	if (att)
		att->release();
	if (tpb)
		tpb->dispose();

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

	return rc;
}