TYPCONV GetTypeConv(); int GetConvSize(); //extern char *JvmPath; // The connect_jvm_path global variable value //extern char *ClassPath; // The connect_class_path global variable value
//char *GetJavaWrapper(void); // The connect_java_wrapper variable value
/***********************************************************************/ /* Some macro's (should be defined elsewhere to be more accessible) */ /***********************************************************************/ //#if defined(_DEBUG) //#define ASSERT(f) assert(f) //#define DEBUG_ONLY(f) (f) //#else // !_DEBUG //#define ASSERT(f) ((void)0) //#define DEBUG_ONLY(f) ((void)0) //#endif // !_DEBUG
// To avoid gcc warning int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
/***********************************************************************/ /* GetJDBCType: returns the SQL_TYPE corresponding to a PLG type. */ /***********************************************************************/ staticshort GetJDBCType(int type)
{ short tp = 0; // NULL
switch (type) { case TYPE_STRING: tp = 12; break; // VARCHAR case TYPE_SHORT: tp = 5; break; // SMALLINT case TYPE_INT: tp = 4; break; // INTEGER case TYPE_DATE: tp = 93; break; // DATE //case TYPE_TIME: tp = 92; break; // TIME //case TYPE_TIMESTAMP: tp = 93; break; // TIMESTAMP case TYPE_BIGINT: tp = -5; break; // BIGINT case TYPE_DOUBLE: tp = 8; break; // DOUBLE case TYPE_TINY: tp = -6; break; // TINYINT case TYPE_DECIM: tp = 3; break; // DECIMAL
} // endswitch type
return tp;
} // end of GetJDBCType
/***********************************************************************/ /* TranslateJDBCType: translate a JDBC Type to a PLG type. */ /***********************************************************************/ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v)
{ int type;
switch (stp) { case -1: // LONGVARCHAR, TEXT case -16: // LONGNVARCHAR, NTEXT (unicode) if (GetTypeConv() != TPC_YES) return TYPE_ERROR; else
len = MY_MIN(abs(len), GetConvSize());
/* fall through */ case12: // VARCHAR if (tn && !stricmp(tn, "TEXT")) // Postgresql returns 12 for TEXT if (GetTypeConv() == TPC_NO) return TYPE_ERROR;
// Postgresql can return this if (len == 0x7FFFFFFF)
len = GetConvSize();
/* fall through */ case -9: // NVARCHAR (unicode) // Postgresql can return this when size is unknown if (len == 0x7FFFFFFF)
len = GetConvSize();
v = 'V'; /* fall through */ case1: // CHAR case -15: // NCHAR (unicode) case -8: // ROWID
type = TYPE_STRING; break; case2: // NUMERIC case3: // DECIMAL case -3: // VARBINARY
type = TYPE_DECIM; break; case4: // INTEGER
type = TYPE_INT; break; case5: // SMALLINT
type = TYPE_SHORT; break; case -6: // TINYINT case -7: // BIT case16: // BOOLEAN
type = TYPE_TINY; break; case6: // FLOAT case7: // REAL case8: // DOUBLE
type = TYPE_DOUBLE; break; case93: // TIMESTAMP, DATETIME
type = TYPE_DATE;
len = 19 + ((prec) ? (prec+1) : 0);
v = (tn && toupper(tn[0]) == 'T') ? 'S' : 'E'; break; case91: // DATE, YEAR
type = TYPE_DATE;
if (!tn || toupper(tn[0]) != 'Y') {
len = 10;
v = 'D';
} else {
len = 4;
v = 'Y';
} // endif len
break; case92: // TIME
type = TYPE_DATE;
len = 8 + ((prec) ? (prec + 1) : 0);
v = 'T'; break; case -5: // BIGINT
type = TYPE_BIGINT; break; case1111: // UNKNOWN or UUID if (!tn || !stricmp(tn, "UUID")) {
type = TYPE_STRING;
len = 36; break;
} // endif tn
/* fall through */ case0: // NULL case -2: // BINARY case -4: // LONGVARBINARY case70: // DATALINK case2000: // JAVA_OBJECT case2001: // DISTINCT case2002: // STRUCT case2003: // ARRAY case2004: // BLOB case2005: // CLOB case2006: // REF case2009: // SQLXML case2011: // NCLOB default:
type = TYPE_ERROR;
len = 0;
} // endswitch type
return type;
} // end of TranslateJDBCType
/***********************************************************************/ /* A helper class to split an optionally qualified table name into */ /* components. */ /* These formats are understood: */ /* "CatalogName.SchemaName.TableName" */ /* "SchemaName.TableName" */ /* "TableName" */ /***********************************************************************/ class SQLQualifiedName { staticconst uint max_parts = 3; // Catalog.Schema.Table
MYSQL_LEX_STRING m_part[max_parts]; char m_buf[512];
void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length)
{
S->str = str;
S->length = length;
} // end of lex_string_set
void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs)
{
DBUG_ASSERT(offs <= S->length);
S->str += offs;
S->length -= offs;
} // end of lex_string_shorten_down
/*********************************************************************/ /* Find the rightmost '.' delimiter and return the length */ /* of the qualifier, including the rightmost '.' delimier. */ /* For example, for the string {"a.b.c",5} it will return 4, */ /* which is the length of the qualifier "a.b." */ /*********************************************************************/
size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S)
{
size_t i; for (i = S->length; i > 0; i--)
{ if (S->str[i - 1] == '.')
{
S->str[i - 1] = '\0'; return i;
}
} return0;
} // end of lex_string_find_qualifier
public: /*********************************************************************/ /* Initialize to the given optionally qualified name. */ /* NULL pointer in "name" is supported. */ /* name qualifier has precedence over schema. */ /*********************************************************************/
SQLQualifiedName(JCATPARM *cap)
{ constchar *name = (constchar *)cap->Tab; char *db = (char *)cap->DB;
size_t len, i;
// Initialize the parts for (i = 0; i < max_parts; i++)
lex_string_set(&m_part[i], NULL, 0);
if (name) { // Initialize the first (rightmost) part
lex_string_set(&m_part[0], m_buf,
strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf);
// Initialize the other parts, if exist. for (i = 1; i < max_parts; i++) { if (!(len = lex_string_find_qualifier(&m_part[i - 1]))) break;
lex_string_set(&m_part[i], m_part[i - 1].str, len - 1);
lex_string_shorten_down(&m_part[i - 1], len);
} // endfor i
} // endif name
// If it was not specified, set schema as the passed db name if (db && !m_part[1].length)
lex_string_set(&m_part[1], db, strlen(db));
} // end of SQLQualifiedName
char *ptr(uint i)
{
DBUG_ASSERT(i < max_parts); return (char *)(m_part[i].length ? m_part[i].str : NULL);
} // end of ptr
size_t length(uint i)
{
DBUG_ASSERT(i < max_parts); return m_part[i].length;
} // end of length
}; // end of class SQLQualifiedName
/***********************************************************************/ /* Allocate the structure used to refer to the result set. */ /***********************************************************************/ static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, PCSZ db,
PCSZ tab, PQRYRES qrp)
{
JCATPARM *cap;
/***********************************************************************/ /* JDBCColumns: constructs the result blocks containing all columns */ /* of a JDBC table that will be retrieved by GetData commands. */ /***********************************************************************/
PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat, int maxres, bool info, PJPARM sjp)
{ int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT,
TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
XFLD fldtyp[] = {FLD_CAT, FLD_SCHEM, FLD_TABNAME, FLD_NAME,
FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH,
FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM}; unsignedint length[] = {0, 0, 0, 0, 6, 0, 10, 10, 6, 6, 6, 0}; bool b[] = {true, true, false, false, false, false, false, false, true, true, false, true}; int i, n, ncol = 12;
PCOLRES crp;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = NULL;
/************************************************************************/ /* Do an evaluation of the result size. */ /************************************************************************/ if (!info) {
jcp = new(g)JDBConn(g, NULL);
if (jcp->Connect(sjp)) // openReadOnly + noJDBCdialog return NULL;
if (table && !strchr(table, '%')) { // We fix a MySQL limit because some data sources return 32767
n = jcp->GetMaxValue(1); // MAX_COLUMNS_IN_TABLE)
maxres = (n > 0) ? MY_MIN(n, 4096) : 4096;
} elseif (!maxres)
maxres = 20000;
if (trace(1))
htrc("JDBCColumns: max=%d len=%d,%d,%d,%d\n",
maxres, length[0], length[1], length[2], length[3]);
/************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS,
buftyp, fldtyp, length, false, true);
for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) if (b[i])
crp->Kdata->SetNullable(true);
if (info || !qrp) // Info table return qrp;
if (trace(1))
htrc("Getting col results ncol=%d\n", qrp->Nbcol);
if (!(cap = AllocCatInfo(g, JCAT_COL, db, table, qrp))) return NULL;
// Colpat cannot be null or empty for some drivers
cap->Pat = (colpat && *colpat) ? colpat : PlugDup(g, "%");
/************************************************************************/ /* Now get the results into blocks. */ /************************************************************************/ if ((n = jcp->GetCatInfo(cap)) >= 0) {
qrp->Nblin = n; // ResetNullValues(cap);
if (trace(1))
htrc("Columns: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
qrp = NULL;
/* Cleanup */
jcp->Close();
/************************************************************************/ /* Return the result pointer for use by GetData routines. */ /************************************************************************/ return qrp;
} // end of JDBCColumns
/**************************************************************************/ /* JDBCSrcCols: constructs the result blocks containing the */ /* description of all the columns of a Srcdef option. */ /**************************************************************************/
PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sjp)
{ char *sqry;
PQRYRES qrp;
JDBConn *jcp = new(g)JDBConn(g, NULL);
if (jcp->Connect(sjp)) return NULL;
if (constchar *p = strstr(src, "%s")) { // Place holder for an eventual where clause
size_t sqry_size = strlen(src) + 3;
sqry = (char*)PlugSubAlloc(g, NULL, sqry_size);
snprintf(sqry, sqry_size, "%.*s1=1%s", (int) (p - src), src, p + 2); // dummy where clause
} else
sqry = (char*)src;
qrp = jcp->GetMetaData(g, sqry);
jcp->Close(); return qrp;
} // end of JDBCSrcCols
/**************************************************************************/ /* JDBCTables: constructs the result blocks containing all tables in */ /* an JDBC database that will be retrieved by GetData commands. */ /**************************************************************************/
PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp, int maxres, bool info, PJPARM sjp)
{ int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING,
TYPE_STRING, TYPE_STRING};
XFLD fldtyp[] = {FLD_CAT, FLD_SCHEM, FLD_NAME, FLD_TYPE, FLD_REM}; unsignedint length[] = {0, 0, 0, 16, 0}; bool b[] = {true, true, false, false, true}; int i, n, ncol = 5;
PCOLRES crp;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = NULL;
/************************************************************************/ /* Do an evaluation of the result size. */ /************************************************************************/ if (!info) { /**********************************************************************/ /* Open the connection with the JDBC data source. */ /**********************************************************************/
jcp = new(g)JDBConn(g, NULL);
if (jcp->Connect(sjp)) return NULL;
if (!maxres)
maxres = 10000; // This is completely arbitrary
n = jcp->GetMaxValue(2); // Max catalog name length
if (trace(1))
htrc("JDBCTables: max=%d len=%d,%d\n", maxres, length[0], length[1]);
/************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES, buftyp,
fldtyp, length, false, true);
for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) if (b[i])
crp->Kdata->SetNullable(true);
if (info || !qrp) return qrp;
// Tabpat cannot be null or empty for some drivers if (!(cap = AllocCatInfo(g, JCAT_TAB, db,
(tabpat && *tabpat) ? tabpat : PlugDup(g, "%"), qrp))) return NULL;
cap->Pat = tabtyp;
if (trace(1))
htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol);
/************************************************************************/ /* Now get the results into blocks. */ /************************************************************************/ if ((n = jcp->GetCatInfo(cap)) >= 0) {
qrp->Nblin = n; // ResetNullValues(cap);
if (trace(1))
htrc("Tables: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
} else
qrp = NULL;
/************************************************************************/ /* Close any local connection. */ /************************************************************************/
jcp->Close();
/************************************************************************/ /* Return the result pointer for use by GetData routines. */ /************************************************************************/ return qrp;
} // end of JDBCTables
/*************************************************************************/ /* JDBCDrivers: constructs the result blocks containing all JDBC */ /* drivers available on the local host. */ /* Called with info=true to have result column names. */ /*************************************************************************/
PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
{ int buftyp[] ={TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING};
XFLD fldtyp[] ={FLD_NAME, FLD_EXTRA, FLD_DEFAULT, FLD_REM }; unsignedint length[] ={ 128, 32, 4, 256 }; bool b[] ={ false, false, false, true }; int i, ncol = 4;
PCOLRES crp;
PQRYRES qrp;
JDBConn *jcp = NULL;
/************************************************************************/ /* Do an evaluation of the result size. */ /************************************************************************/ if (!info) {
jcp = new(g) JDBConn(g, NULL);
if (jcp->Open(g) != RC_OK) return NULL;
if (!maxres)
maxres = 256; // Estimated max number of drivers
} else
maxres = 0;
if (trace(1))
htrc("JDBCDrivers: max=%d len=%d\n", maxres, length[0]);
/************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/
qrp = PlgAllocResult(g, ncol, maxres, 0, buftyp, fldtyp, length, false, true);
for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) { if (b[i])
crp->Kdata->SetNullable(true);
/************************************************************************/ /* Now get the results into blocks. */ /************************************************************************/ if (!info && qrp && jcp->GetDrivers(qrp))
qrp = NULL;
if (!info)
jcp->Close();
/************************************************************************/ /* Return the result pointer for use by GetData routines. */ /************************************************************************/ return qrp;
} // end of JDBCDrivers
/***********************************************************************/ /* AddJars: add some jar file to the Class path. */ /***********************************************************************/ void JDBConn::AddJars(PSTRG jpop, char sep)
{ #ifdefined(DEVELOPMENT)
jpop->Append( ";C:/Jconnectors/postgresql-9.4.1208.jar" ";C:/Oracle/ojdbc7.jar" ";C:/Apache/commons-dbcp2-2.1.1/commons-dbcp2-2.1.1.jar" ";C:/Apache/commons-pool2-2.4.2/commons-pool2-2.4.2.jar" ";C:/Apache/commons-logging-1.2/commons-logging-1.2.jar" ";C:/Jconnectors/mysql-connector-java-6.0.2-bin.jar" ";C:/Jconnectors/mariadb-java-client-2.0.1.jar" ";C:/Jconnectors/sqljdbc42.jar"); #endif// DEVELOPMENT
} // end of AddJars
/***********************************************************************/ /* Connect: connect to a data source. */ /***********************************************************************/ bool JDBConn::Connect(PJPARM sop)
{ bool err = false;
jint rc;
PGLOBAL& g = m_G;
/*******************************************************************/ /* Create or attach a JVM. */ /*******************************************************************/ if (Open(g)) returntrue;
if (!sop) // DRIVER catalog table returnfalse;
jmethodID cid = nullptr;
if (gmID(g, cid, "JdbcConnect", "([Ljava/lang/String;IZ)I")) returntrue;
// Build the java string array
jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4
env->FindClass("java/lang/String"), NULL); // Strings
if (!gmID(g, qcid, "GetQuoteString", "()Ljava/lang/String;")) {
jstring s = (jstring)env->CallObjectMethod(job, qcid);
if (s != nullptr) { char *qch = GetUTFString(s);
m_IDQuoteChar[0] = *qch;
} else {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = GetUTFString(s);
} // endif s
} // endif qcid
if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I")) returntrue; else
m_Connected = true;
returnfalse;
} // end of Connect
/***********************************************************************/ /* Execute an SQL command. */ /***********************************************************************/ int JDBConn::ExecuteCommand(PCSZ sql)
{ int rc;
jint n;
jstring qry;
PGLOBAL& g = m_G;
// Get the methods used to execute a query and get the result if (gmID(g, xid, "Execute", "(Ljava/lang/String;)I") ||
gmID(g, grs, "GetResult", "()I")) return RC_FX;
qry = env->NewStringUTF(sql);
n = env->CallIntMethod(job, xid, qry);
env->DeleteLocalRef(qry);
if (Check(n)) {
snprintf(g->Message, sizeof(g->Message), "Execute: %s", Msg); return RC_FX;
} // endif n
m_Ncol = env->CallIntMethod(job, grs);
if (Check(m_Ncol)) {
snprintf(g->Message, sizeof(g->Message), "GetResult: %s", Msg);
rc = RC_FX;
} elseif (m_Ncol) {
snprintf(g->Message, sizeof(g->Message), "Result set column number");
rc = RC_OK; // A result set was returned
} else {
m_Aff = (int)n; // Affected rows
snprintf(g->Message, sizeof(g->Message), "Affected rows");
rc = RC_NF;
} // endif ncol
return rc;
} // end of ExecuteCommand
/***********************************************************************/ /* Fetch next row. */ /***********************************************************************/ int JDBConn::Fetch(int pos)
{
jint rc = JNI_ERR;
PGLOBAL& g = m_G;
if (m_Full) // Result set has one row return1;
if (pos) { if (!m_Scrollable) {
snprintf(g->Message, sizeof(g->Message), "Cannot fetch(pos) if FORWARD ONLY"); return rc;
} elseif (gmID(m_G, fetchid, "Fetch", "(I)Z")) return rc;
if (env->CallBooleanMethod(job, fetchid, pos))
rc = m_Rows;
} else { if (gmID(g, readid, "ReadNext", "()I")) return rc;
rc = env->CallBooleanMethod(job, readid);
if (!Check(rc)) { if (rc == 0)
m_Full = (m_Fetch == 1); else
m_Fetch++;
/***********************************************************************/ /* Restart from beginning of result set */ /***********************************************************************/ int JDBConn::Rewind(PCSZ sql)
{ int rbuf = -1;
if (m_Full)
rbuf = m_Rows; // No need to "rewind" elseif (m_Scrollable) { if (gmID(m_G, fetchid, "Fetch", "(I)Z")) return -1;
/***********************************************************************/ /* Retrieve and set the column value from the result set. */ /***********************************************************************/ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
{ constchar *field;
PGLOBAL& g = m_G;
jint ctyp;
jstring cn, jn = nullptr;
jobject jb = nullptr;
if (rank == 0) if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
snprintf(g->Message, sizeof(g->Message), "Fail to allocate jstring %s", SVP(name)); throw (int)TYPE_AM_JDBC;
} // endif name
// Returns 666 is case of error
ctyp = env->CallIntMethod(job, typid, rank, jn);
/***********************************************************************/ /* Prepare an SQL statement for insert. */ /***********************************************************************/ bool JDBConn::PrepareSQL(PCSZ sql)
{ bool b = true;
PGLOBAL& g = m_G;
if (!gmID(g, prepid, "CreatePrepStmt", "(Ljava/lang/String;)I")) { // Create the prepared statement
jstring qry = env->NewStringUTF(sql);
if (Check(env->CallBooleanMethod(job, prepid, qry)))
snprintf(g->Message, sizeof(g->Message), "CreatePrepStmt: %s", Msg); else
b = false;
env->DeleteLocalRef(qry);
} // endif prepid
return b;
} // end of PrepareSQL
/***********************************************************************/ /* Execute an SQL query that returns a result set. */ /***********************************************************************/ int JDBConn::ExecuteQuery(PCSZ sql)
{ int rc = RC_FX;
jint ncol;
jstring qry;
PGLOBAL& g = m_G;
// Get the methods used to execute a query and get the result if (!gmID(g, xqid, "ExecuteQuery", "(Ljava/lang/String;)I")) {
qry = env->NewStringUTF(sql);
ncol = env->CallIntMethod(job, xqid, qry);
/***********************************************************************/ /* Execute an SQL query and get the affected rows. */ /***********************************************************************/ int JDBConn::ExecuteUpdate(PCSZ sql)
{ int rc = RC_FX;
jint n;
jstring qry;
PGLOBAL& g = m_G;
// Get the methods used to execute a query and get the affected rows if (!gmID(g, xuid, "ExecuteUpdate", "(Ljava/lang/String;)I")) {
qry = env->NewStringUTF(sql);
n = env->CallIntMethod(job, xuid, qry);
/***********************************************************************/ /* Get the number of lines of the result set. */ /***********************************************************************/ int JDBConn::GetResultSize(PCSZ sql, PCOL colp)
{ int rc;
m_Full = false; return colp->GetIntValue();
} // end of GetResultSize
/***********************************************************************/ /* Execute a prepared statement. */ /***********************************************************************/ int JDBConn::ExecuteSQL(void)
{ int rc = RC_FX;
PGLOBAL& g = m_G;
// Get the methods used to execute a prepared statement if (!gmID(g, xpid, "ExecutePrep", "()I")) {
jint n = env->CallIntMethod(job, xpid);
if (n == -3)
snprintf(g->Message, sizeof(g->Message), "SQL statement is not prepared"); elseif (Check(n))
snprintf(g->Message, sizeof(g->Message), "ExecutePrep: %s", Msg); else {
m_Aff = (int)n;
rc = RC_OK;
} // endswitch n
} // endif xpid
return rc;
} // end of ExecuteSQL
/***********************************************************************/ /* Set a parameter for inserting. */ /***********************************************************************/ bool JDBConn::SetParam(JDBCCOL *colp)
{
PGLOBAL& g = m_G; bool rc = false;
PVAL val = colp->GetValue();
jint n, jrc = 0, i = (jint)colp->GetRank();
jshort s;
jlong lg; //jfloat f;
jdouble d;
jclass dat;
jobject datobj;
jstring jst = nullptr;
jmethodID dtc, setid = nullptr;
if (val->GetNullable() && val->IsNull()) { if (gmID(g, setid, "SetNullParm", "(II)I")) returntrue;
jrc = env->CallIntMethod(job, setid, i,
(colp->uuid ? 1111 : (jint)GetJDBCType(val->GetType())));
} elseif (colp->uuid) { if (gmID(g, setid, "SetUuidParm", "(ILjava/lang/String;)V")) returntrue;
jst = env->NewStringUTF(val->GetCharValue());
env->CallVoidMethod(job, setid, i, jst);
} elseswitch (val->GetType()) { case TYPE_STRING: if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V")) returntrue;
jst = env->NewStringUTF(val->GetCharValue());
env->CallVoidMethod(job, setid, i, jst); break; case TYPE_INT: if (gmID(g, setid, "SetIntParm", "(II)V")) returntrue;
n = (jint)val->GetIntValue();
env->CallVoidMethod(job, setid, i, n); break; case TYPE_TINY: case TYPE_SHORT: if (gmID(g, setid, "SetShortParm", "(IS)V")) returntrue;
s = (jshort)val->GetShortValue();
env->CallVoidMethod(job, setid, i, s); break; case TYPE_BIGINT: if (gmID(g, setid, "SetBigintParm", "(IJ)V")) returntrue;
lg = (jlong)val->GetBigintValue();
env->CallVoidMethod(job, setid, i, lg); break; case TYPE_DOUBLE: case TYPE_DECIM: if (gmID(g, setid, "SetDoubleParm", "(ID)V")) returntrue;
d = (jdouble)val->GetFloatValue();
env->CallVoidMethod(job, setid, i, d); break; case TYPE_DATE: if ((dat = env->FindClass("java/sql/Timestamp")) == nullptr) {
snprintf(g->Message, sizeof(g->Message), "Cannot find Timestamp class"); returntrue;
} elseif (!(dtc = env->GetMethodID(dat, "<init>", "(J)V"))) {
snprintf(g->Message, sizeof(g->Message), "Cannot find Timestamp class constructor"); returntrue;
} // endif's
env->CallVoidMethod(job, setid, i, datobj); break; default:
snprintf(g->Message, sizeof(g->Message), "Parm type %d not supported", val->GetType()); returntrue;
} // endswitch Type
/***********************************************************************/ /* Get the list of Drivers and set it in qrp. */ /***********************************************************************/ bool JDBConn::GetDrivers(PQRYRES qrp)
{
PSZ sval; int i, n, size;
PCOLRES crp;
jstring js;
jmethodID gdid = nullptr;
if (gmID(m_G, gdid, "GetDrivers", "([Ljava/lang/String;I)I")) returntrue;
// Build the java string array
jobjectArray s = env->NewObjectArray(4 * qrp->Maxres,
env->FindClass("java/lang/String"), NULL);
qrp->Nblin = size; returnfalse;
} // end of GetDrivers
/**************************************************************************/ /* GetMetaData: constructs the result blocks containing the */ /* description of all the columns of an SQL command. */ /**************************************************************************/
PQRYRES JDBConn::GetMetaData(PGLOBAL g, PCSZ src)
{ staticint buftyp[] = {TYPE_STRING, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_INT}; static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_PREC,
FLD_SCALE, FLD_NULL }; staticunsignedint length[] = {0, 6, 10, 6, 6}; constchar *name; int len, qcol = 5;
PQRYRES qrp = NULL;
PCOLRES crp;
ushort i;
jint *n = nullptr;
jstring label;
jmethodID colid = nullptr; int rc = ExecuteCommand(src);
if (rc == RC_NF) {
snprintf(g->Message, sizeof(g->Message), "Srcdef is not returning a result set"); return NULL;
} elseif ((rc) == RC_FX) { return NULL;
} elseif (m_Ncol == 0) {
snprintf(g->Message, sizeof(g->Message), "Invalid Srcdef"); return NULL;
} // endif's
if (gmID(g, colid, "ColumnDesc", "(I[I)Ljava/lang/String;")) return NULL;
// Get max column name length
len = GetMaxValue(5);
length[0] = (len > 0) ? len + 1 : 128;
/************************************************************************/ /* Allocate the structures used to refer to the result set. */ /************************************************************************/ if (!(qrp = PlgAllocResult(g, qcol, m_Ncol, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, true))) return NULL;
// Some columns must be renamed for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) switch (++i) { case3: crp->Name = "Precision"; break; case4: crp->Name = "Scale"; break; case5: crp->Name = "Nullable"; break;
} // endswitch i
// Build the java int array
jintArray val = env->NewIntArray(4);
/************************************************************************/ /* Now get the results into blocks. */ /************************************************************************/ for (i = 0; i < m_Ncol; i++) { if (!(label = (jstring)env->CallObjectMethod(job, colid, i + 1, val))) { if (Check())
snprintf(g->Message, sizeof(g->Message), "ColumnDesc: %s", Msg); else
snprintf(g->Message, sizeof(g->Message), "No result metadata");
env->ReleaseIntArrayElements(val, n, 0); return NULL;
} // endif label
/* Cleanup */
env->ReleaseIntArrayElements(val, n, 0);
/************************************************************************/ /* Return the result pointer for use by GetData routines. */ /************************************************************************/ return qrp;
} // end of GetMetaData
/***********************************************************************/ /* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */ /***********************************************************************/ int JDBConn::GetCatInfo(JCATPARM *cap)
{
PGLOBAL& g = m_G; // void *buffer; int i, ncol;
PCSZ fnc = "Unknown";
uint n; short len, tp;
PQRYRES qrp = cap->Qrp;
PCOLRES crp;
jboolean rc = false; // HSTMT hstmt = NULL; // SQLLEN *vl, *vlen = NULL;
PVAL *pval = NULL; char* *pbuf = NULL;
jobjectArray parms;
jmethodID catid = nullptr;
if (trace(1))
htrc("Method %s returned %d columns\n", fnc, ncol);
// n because we no more ignore the first column if ((n = qrp->Nbcol) > (uint)ncol) {
snprintf(g->Message, sizeof(g->Message), MSG(COL_NUM_MISM)); return -1;
} // endif n
// Unconditional to handle STRBLK's
pval = (PVAL *)PlugSubAlloc(g, NULL, n * sizeof(PVAL)); // vlen = (SQLLEN *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN));
pbuf = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*));
// Now fetch the result for (i = 0; i < qrp->Maxres; i++) { if (Check(rc = Fetch(0))) {
snprintf(g->Message, sizeof(g->Message), "Fetch: %s", Msg); return -1;
} if (rc == 0) { if (trace(1))
htrc("End of fetches i=%d\n", i);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.