-
-
Save kubo/0b63c8148c4a77f3f9f9c21194c78d47 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <oci.h> | |
#include <xmlproc.h> | |
#define CHARSET_ID_UTF8 873 | |
#define chke(func) do { \ | |
sword rv = func; \ | |
fprintf(stderr, "%s => %d\n", #func, rv); \ | |
if (rv == OCI_ERROR) { \ | |
sb4 errcode; \ | |
char errmsg[OCI_ERROR_MAXMSG_SIZE]; \ | |
OCIErrorGet(envhp, 1, NULL, &errcode, (OraText*)errmsg, sizeof(errmsg), OCI_HTYPE_ENV); \ | |
fprintf(stderr, " %s\n", errmsg); \ | |
} \ | |
} while (0) | |
#define chk(func) do { \ | |
sword rv = func; \ | |
fprintf(stderr, "%s => %d\n", #func, rv); \ | |
if (rv == OCI_ERROR) { \ | |
sb4 errcode; \ | |
char errmsg[OCI_ERROR_MAXMSG_SIZE]; \ | |
OCIErrorGet(errhp, 1, NULL, &errcode, (OraText*)errmsg, sizeof(errmsg), OCI_HTYPE_ERROR); \ | |
fprintf(stderr, " %s\n", errmsg); \ | |
} \ | |
} while (0) | |
static void insert_xml(OCISvcCtx *svchp, OCIError *errhp, OCIType *xmltdo, xmlctx *xctx, const char *tag, const char *content); | |
static void select_xml(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp, OCIType *xmltdo, xmlctx *xctx, const char *tag_expected, const char *content_expected); | |
static const char *env(const char *name, const char *default_value) | |
{ | |
const char *value = getenv(name); | |
return value ? value : default_value; | |
} | |
int main() | |
{ | |
const char *username = env("ODPIC_TEST_MAIN_USER", "odpic"); | |
const char *password = env("ODPIC_TEST_MAIN_PASSWORD", "welcome"); | |
const char *database = env("ODPIC_TEST_CONNECT_STRING", "localhost/orclpdb"); | |
OCIEnv *envhp; | |
OCIError *errhp; | |
OCISvcCtx *svchp; | |
OCIType *xmltdo; | |
const char *tag = "data"; | |
size_t content_size = 64 * 1024 - 2; | |
char *content = malloc(content_size + 1); | |
memset(content, 'x', content_size); | |
content[content_size] = '\0'; | |
chke(OCIEnvNlsCreate(&envhp, OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL, CHARSET_ID_UTF8, CHARSET_ID_UTF8)); | |
chke(OCIHandleAlloc(envhp, (void**)&errhp, OCI_HTYPE_ERROR, 0, NULL)); | |
chk(OCILogon(envhp, errhp, &svchp, (OraText*)username, strlen(username), (OraText*)password, strlen(password), (OraText*)database, strlen(database))); | |
chk(OCITypeByName(envhp, errhp, svchp, (const OraText*)"SYS", 3, (const OraText*)"XMLTYPE", 7, NULL, 0, OCI_DURATION_SESSION, OCI_TYPEGET_ALL, &xmltdo)); | |
xmlctx *xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, NULL, 0); | |
insert_xml(svchp, errhp, xmltdo, xctx, tag, content); | |
select_xml(envhp, svchp, errhp, xmltdo, xctx, tag, content); | |
OCIXmlDbFreeXmlCtx(xctx); | |
chk(OCITransRollback(svchp, errhp, OCI_DEFAULT)); | |
chk(OCILogoff(svchp, errhp)); | |
} | |
static void insert_xml(OCISvcCtx *svchp, OCIError *errhp, OCIType *xmltdo, xmlctx *xctx, const char *tag, const char *content) | |
{ | |
const char *sql = "insert into TestXML (IntCol, XMLCol) values (1, :xml)"; | |
OCIStmt *stmtp; | |
OCIBind *bindp; | |
xmlerr err; | |
xmldocnode *doc; | |
xmlelemnode *top_elem; | |
int i; | |
doc = XmlCreateDocument(xctx, NULL, NULL, NULL, &err); | |
top_elem = XmlDomCreateElem(xctx, doc, (oratext*)tag); | |
XmlDomAppendChild(xctx, (xmlnode*)doc, (xmlnode*)top_elem); | |
for (i = 0; i < 10; i++) { | |
xmlelemnode *elem = XmlDomCreateElem(xctx, doc, (oratext*)tag); | |
xmltextnode *text = XmlDomCreateText(xctx, doc, (oratext*)content); | |
XmlDomAppendChild(xctx, (xmlnode*)top_elem, (xmlnode*)elem); | |
XmlDomAppendChild(xctx, (xmlnode*)elem, (xmlnode*)text); | |
} | |
chk(OCIStmtPrepare2(svchp, &stmtp, errhp, (OraText*)sql, strlen(sql), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)); | |
chk(OCIBindByPos(stmtp, &bindp, errhp, 1, NULL, 0, SQLT_NTY, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT)); | |
chk(OCIBindObject(bindp, errhp, xmltdo, (void*)&doc, NULL, NULL, NULL)); | |
chk(OCIStmtExecute(svchp, stmtp, errhp, 1, 0, NULL, NULL, OCI_DEFAULT)); | |
chk(OCIStmtRelease(stmtp, errhp, NULL, 0, OCI_DEFAULT)); | |
XmlFreeDocument(xctx, doc); | |
} | |
static void select_xml(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp, OCIType *xmltdo, xmlctx *xctx, const char *tag_expected, const char *content_expected) | |
{ | |
const char *sql = "select XMLCol from TestXML where IntCol = 1"; | |
OCIStmt *stmtp; | |
OCIDefine *defnp; | |
xmldocnode *doc = NULL; | |
xmlelemnode *elem; | |
xmltextnode *text; | |
const char *tag, *content; | |
int i; | |
chk(OCIStmtPrepare2(svchp, &stmtp, errhp, (OraText*)sql, strlen(sql), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT)); | |
chk(OCIDefineByPos(stmtp, &defnp, errhp, 1, NULL, 0, SQLT_NTY, NULL, NULL, NULL, OCI_DEFAULT)); | |
chk(OCIDefineObject(defnp, errhp, xmltdo, (void*)&doc, NULL, NULL, NULL)); | |
chk(OCIStmtExecute(svchp, stmtp, errhp, 1, 0, NULL, NULL, OCI_DEFAULT)); | |
chk(OCIStmtRelease(stmtp, errhp, NULL, 0, OCI_DEFAULT)); | |
elem = XmlDomGetDocElem(xctx, doc); | |
tag = (const char*)XmlDomGetTag(xctx, elem); | |
if (strcmp(tag, tag_expected) != 0) { | |
fprintf(stderr, "tag: expected '%s' but '%s'\n", tag_expected, tag); | |
} | |
for (i = 0; i < 10; i++) { | |
if (i == 0) { | |
elem = XmlDomGetFirstChild(xctx, elem); | |
} else { | |
elem = XmlDomGetNextSibling(xctx, elem); | |
} | |
tag = (const char*)XmlDomGetTag(xctx, elem); | |
if (strcmp(tag, tag_expected) != 0) { | |
fprintf(stderr, "tag: expected '%s' but '%s'\n", tag_expected, tag); | |
} | |
text = XmlDomGetFirstChild(xctx, elem); | |
content = (const char*)XmlDomGetCharData(xctx, text); | |
if (strcmp(content, content_expected) != 0) { | |
fprintf(stderr, "content: expected '%.100s...'(up to 100 bytes) but '%s'\n", content_expected, content); | |
} | |
} | |
chk(OCIObjectFree(envhp, errhp, doc, 0)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment