| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /*
- * PROGRAM: Object oriented API samples.
- * MODULE: 07.blob.cpp
- * DESCRIPTION: A sample of loading data into blob and reading.
- * Run second time (when database already exists) to see
- * how FbException is caught and handled by this code.
- *
- * Example for the following interfaces:
- * IAttachment - use of open and create blob methods
- * IBlob - interface to work with blobs
- *
- * The contents of this file are subject to the Initial
- * Developer's Public License Version 1.0 (the "License");
- * you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
- *
- * Software distributed under the License is distributed AS IS,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.
- * See the License for the specific language governing rights
- * and limitations under the License.
- *
- * The Original Code was created by Alexander Peshkoff
- * for the Firebird Open Source RDBMS project.
- *
- * Copyright (c) 2016 Alexander Peshkoff <[email protected]>
- * and all contributors signed below.
- *
- * All Rights Reserved.
- * Contributor(s): ______________________________________.
- */
- #include "ifaceExamples.h"
- #include <firebird/Message.h>
- static IMaster* master = fb_get_master_interface();
- static const char* testData[] = {
- "This is test data",
- "that is inserted during example execution",
- "into blobs_table",
- NULL
- };
- static void errPrint(IStatus* status)
- {
- char buf[256];
- master->getUtilInterface()->formatStatus(buf, sizeof(buf), status);
- fprintf(stderr, "%s\n", buf);
- }
- static void drop(IAttachment** att)
- {
- // With CheckStatusWrapper passed as status interface noting is thrown on error
- // You should check status yourself
- CheckStatusWrapper status(master->getStatus());
- // drop database (will close interface)
- (*att)->dropDatabase(&status);
- if (status.getState() & IStatus::STATE_ERRORS)
- {
- errPrint(&status);
- fprintf(stderr, "*** Drop database failed - do it manually before next run ***\n");
- }
- else
- *att = NULL;
- // cleanup
- status.dispose();
- }
- int main()
- {
- int rc = 0;
- // set default password if none specified in environment
- setenv("ISC_USER", "sysdba", 0);
- setenv("ISC_PASSWORD", "masterkey", 0);
- // With ThrowStatusWrapper passed as status interface FbException will be thrown on error
- ThrowStatusWrapper status(master->getStatus());
- // Declare pointers to required interfaces
- IProvider* prov = master->getDispatcher();
- IAttachment* att = NULL;
- ITransaction* tra = NULL;
- IBlob* blob = NULL;
- try
- {
- // create database
- att = prov->createDatabase(&status, "blob_07.fdb", 0, NULL);
- tra = att->startTransaction(&status, 0, NULL);
- // create table
- att->execute(&status, tra, 0, "create table blobs_table (b blob sub_type text)", SAMPLES_DIALECT,
- NULL, NULL, NULL, NULL);
- tra->commitRetaining(&status);
- // Message for data exchange
- FB_MESSAGE(Msg, ThrowStatusWrapper,
- (FB_BLOB, b)
- ) message(&status, master);
- message.clear();
- // create blob
- blob = att->createBlob(&status, tra, &message->b, 0, NULL);
- // populate blob with data
- for (const char** seg = testData; *seg; ++seg)
- blob->putSegment(&status, strlen(*seg), *seg);
- blob->close(&status);
- blob = NULL;
- // insert blob into the table
- att->execute(&status, tra, 0, "insert into blobs_table(b) values(?)", SAMPLES_DIALECT,
- message.getMetadata(), message.getData(), NULL, NULL);
- tra->commitRetaining(&status);
- printf("Test blob inserted into blobs_table\n...\n");
- // Read blob from table
- message.clear();
- att->execute(&status, tra, 0, "select first(1) b from blobs_table", SAMPLES_DIALECT,
- NULL, NULL, message.getMetadata(), message.getData());
- blob = att->openBlob(&status, tra, &message->b, 0, NULL);
- // Read segments from blob
- // Use very small segment buffer to show read of incomplete segment
- printf("Read inserted blob from blobs_table\n...\n");
- int bufOver = 0;
- for(bool eof = false; !eof; )
- {
- const char* lineFeed = "\n";
- char buf[32];
- unsigned l = 0;
- switch (blob->getSegment(&status, sizeof(buf) - 1, buf, &l))
- {
- case IStatus::RESULT_OK:
- break;
- case IStatus::RESULT_SEGMENT:
- lineFeed = "";
- bufOver++;
- break;
- default:
- eof = true;
- continue;
- }
- buf[l] = 0;
- printf("%s%s", buf, lineFeed);
- }
- printf("\nSegment not fit in buffer counter = %d\n\n", bufOver);
- // cleanup
- blob->close(&status);
- blob = NULL;
- tra->commit(&status);
- tra = NULL;
- // uncomment next line to play with errors during drop database
- // printf("Attach with any client to blob_07.fdb to prevent it being dropped and press enter"); getchar();
- // drop database
- drop(&att);
- }
- catch (const FbException& error)
- {
- // handle error
- rc = 1;
- errPrint(error.getStatus());
- if (att)
- drop(&att);
- }
- // release interfaces after error caught
- if (blob)
- blob->release();
- if (tra)
- tra->release();
- if (att)
- att->release();
- status.dispose();
- prov->release();
- return rc;
- }
|