LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mdb - ogrmdbjackcess.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 386 334 86.5 %
Date: 2012-12-26 Functions: 28 21 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmdbjackcess.cpp 22156 2011-04-13 20:08:07Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRMDBJavaEnv class.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_mdb.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogrmdbjackcess.cpp 22156 2011-04-13 20:08:07Z rouault $");
      33                 : 
      34                 : static JavaVM *jvm_static = NULL;
      35                 : static JNIEnv *env_static = NULL;
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                         OGRMDBJavaEnv()                              */
      39                 : /************************************************************************/
      40                 : 
      41               6 : OGRMDBJavaEnv::OGRMDBJavaEnv()
      42                 : {
      43               6 :     jvm = NULL;
      44               6 :     env = NULL;
      45               6 :     bCalledFromJava = FALSE;
      46                 : 
      47               6 :     byteArray_class = NULL;
      48                 : 
      49               6 :     file_class = NULL;
      50               6 :     file_constructor = NULL;
      51               6 :     database_class = NULL;
      52               6 :     database_open = NULL;
      53               6 :     database_close = NULL;
      54               6 :     database_getTableNames = NULL;
      55               6 :     database_getTable = NULL;
      56                 : 
      57               6 :     table_class = NULL;
      58               6 :     table_getColumns = NULL;
      59               6 :     table_iterator = NULL;
      60               6 :     table_getRowCount = NULL;
      61                 : 
      62               6 :     column_class = NULL;
      63               6 :     column_getName = NULL;
      64               6 :     column_getType = NULL;
      65               6 :     column_getLength = NULL;
      66               6 :     column_isVariableLength = NULL;
      67                 : 
      68               6 :     datatype_class = NULL;
      69               6 :     datatype_getValue = NULL;
      70                 : 
      71               6 :     list_class = NULL;
      72               6 :     list_iterator = NULL;
      73                 : 
      74               6 :     set_class = NULL;
      75               6 :     set_iterator = NULL;
      76                 : 
      77               6 :     map_class = NULL;
      78               6 :     map_get = NULL;
      79                 : 
      80               6 :     iterator_class = NULL;
      81               6 :     iterator_hasNext = NULL;
      82               6 :     iterator_next = NULL;
      83                 : 
      84               6 :     object_class = NULL;
      85               6 :     object_toString = NULL;
      86               6 :     object_getClass = NULL;
      87                 : 
      88               6 :     boolean_class = NULL;
      89               6 :     boolean_booleanValue = NULL;
      90                 : 
      91               6 :     byte_class = NULL;
      92               6 :     byte_byteValue = NULL;
      93                 : 
      94               6 :     short_class = NULL;
      95               6 :     short_shortValue = NULL;
      96                 : 
      97               6 :     integer_class = NULL;
      98               6 :     integer_intValue = NULL;
      99                 : 
     100               6 :     float_class = NULL;
     101               6 :     float_floatValue = NULL;
     102                 : 
     103               6 :     double_class = NULL;
     104               6 :     double_doubleValue = NULL;
     105               6 : }
     106                 : 
     107                 : /************************************************************************/
     108                 : /*                        ~OGRMDBJavaEnv()                              */
     109                 : /************************************************************************/
     110                 : 
     111               6 : OGRMDBJavaEnv::~OGRMDBJavaEnv()
     112                 : {
     113               6 :     if (jvm)
     114                 :     {
     115               6 :         env->DeleteLocalRef(byteArray_class);
     116                 : 
     117               6 :         env->DeleteLocalRef(file_class);
     118               6 :         env->DeleteLocalRef(database_class);
     119                 : 
     120               6 :         env->DeleteLocalRef(table_class);
     121                 : 
     122               6 :         env->DeleteLocalRef(column_class);
     123                 : 
     124               6 :         env->DeleteLocalRef(datatype_class);
     125                 : 
     126               6 :         env->DeleteLocalRef(list_class);
     127                 : 
     128               6 :         env->DeleteLocalRef(set_class);
     129                 : 
     130               6 :         env->DeleteLocalRef(map_class);
     131                 : 
     132               6 :         env->DeleteLocalRef(iterator_class);
     133                 : 
     134               6 :         env->DeleteLocalRef(object_class);
     135                 : 
     136               6 :         env->DeleteLocalRef(boolean_class);
     137               6 :         env->DeleteLocalRef(byte_class);
     138               6 :         env->DeleteLocalRef(short_class);
     139               6 :         env->DeleteLocalRef(integer_class);
     140               6 :         env->DeleteLocalRef(float_class);
     141               6 :         env->DeleteLocalRef(double_class);
     142                 : 
     143                 :         /*if (!bCalledFromJava)
     144                 :         {
     145                 :             CPLDebug("MDB", "Destroying JVM");
     146                 :             int ret = jvm->DestroyJavaVM();
     147                 :             CPLDebug("MDB", "ret=%d", ret);
     148                 :         }*/
     149                 :     }
     150               6 : }
     151                 : 
     152                 : #define CHECK(x, y) do {x = y; if (!x) { CPLError(CE_Failure, CPLE_AppDefined, #y " failed"); return FALSE;} } while(0)
     153                 : 
     154                 : /************************************************************************/
     155                 : /*                              Init()                                  */
     156                 : /************************************************************************/
     157                 : 
     158               6 : int OGRMDBJavaEnv::Init()
     159                 : {
     160               6 :     if (jvm_static == NULL)
     161                 :     {
     162                 :         JavaVM* vmBuf[1];
     163                 :         jsize nVMs;
     164                 : 
     165                 :         /* Are we already called from Java ? */
     166               3 :         if (JNI_GetCreatedJavaVMs(vmBuf, 1, &nVMs) == JNI_OK && nVMs == 1)
     167                 :         {
     168               0 :             jvm = vmBuf[0];
     169               0 :             if (jvm->GetEnv((void **)&env, JNI_VERSION_1_2) == JNI_OK)
     170                 :             {
     171               0 :                 bCalledFromJava = TRUE;
     172                 :             }
     173                 :             else
     174                 :             {
     175               0 :                 jvm = NULL;
     176               0 :                 env = NULL;
     177                 :             }
     178                 :         }
     179                 :         else
     180                 :         {
     181                 :             JavaVMInitArgs args;
     182                 :             JavaVMOption options[1];
     183               3 :             args.version = JNI_VERSION_1_2;
     184               3 :             const char* pszClassPath = CPLGetConfigOption("CLASSPATH", NULL);
     185               3 :             CPLString osClassPathOption;
     186               3 :             if (pszClassPath)
     187                 :             {
     188               3 :                 args.nOptions = 1;
     189               3 :                 osClassPathOption.Printf("-Djava.class.path=%s", pszClassPath);
     190               3 :                 options[0].optionString = (char*) osClassPathOption.c_str();
     191               3 :                 args.options = options;
     192                 :             }
     193                 :             else
     194               0 :                 args.nOptions = 0;
     195               3 :             args.ignoreUnrecognized = JNI_FALSE;
     196                 : 
     197               3 :             int ret = JNI_CreateJavaVM(&jvm, (void **)&env, &args);
     198               3 :             if (ret != 0 || jvm == NULL || env == NULL)
     199                 :             {
     200               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "JNI_CreateJavaVM failed (%d)", ret);
     201               0 :                 return FALSE;
     202                 :             }
     203                 : 
     204               3 :             jvm_static = jvm;
     205               3 :             env_static = env;
     206                 :         }
     207                 :     }
     208                 :     else
     209                 :     {
     210               3 :         jvm = jvm_static;
     211               3 :         env = env_static;
     212                 :     }
     213                 : 
     214               6 :     CHECK(byteArray_class, env->FindClass("[B"));
     215               6 :     CHECK(file_class, env->FindClass("java/io/File"));
     216               6 :     CHECK(file_constructor, env->GetMethodID(file_class, "<init>", "(Ljava/lang/String;)V"));
     217               6 :     CHECK(database_class, env->FindClass("com/healthmarketscience/jackcess/Database"));
     218                 : 
     219               6 :     CHECK(database_open, env->GetStaticMethodID(database_class, "open", "(Ljava/io/File;Z)Lcom/healthmarketscience/jackcess/Database;"));
     220               6 :     CHECK(database_close, env->GetMethodID(database_class, "close", "()V"));
     221               6 :     CHECK(database_getTableNames, env->GetMethodID(database_class, "getTableNames", "()Ljava/util/Set;"));
     222               6 :     CHECK(database_getTable, env->GetMethodID(database_class, "getTable", "(Ljava/lang/String;)Lcom/healthmarketscience/jackcess/Table;"));
     223                 : 
     224               6 :     CHECK(table_class, env->FindClass("com/healthmarketscience/jackcess/Table"));
     225               6 :     CHECK(table_getColumns, env->GetMethodID(table_class, "getColumns", "()Ljava/util/List;"));
     226               6 :     CHECK(table_iterator, env->GetMethodID(table_class, "iterator", "()Ljava/util/Iterator;"));
     227               6 :     CHECK(table_getRowCount, env->GetMethodID(table_class, "getRowCount", "()I"));
     228                 : 
     229               6 :     CHECK(column_class, env->FindClass("com/healthmarketscience/jackcess/Column"));
     230               6 :     CHECK(column_getName, env->GetMethodID(column_class, "getName", "()Ljava/lang/String;"));
     231               6 :     CHECK(column_getType, env->GetMethodID(column_class, "getType", "()Lcom/healthmarketscience/jackcess/DataType;"));
     232               6 :     CHECK(column_getLength, env->GetMethodID(column_class, "getLength", "()S"));
     233               6 :     CHECK(column_isVariableLength, env->GetMethodID(column_class, "isVariableLength", "()Z"));
     234                 : 
     235               6 :     CHECK(datatype_class, env->FindClass("com/healthmarketscience/jackcess/DataType"));
     236               6 :     CHECK(datatype_getValue, env->GetMethodID(datatype_class, "getValue", "()B"));
     237                 : 
     238               6 :     CHECK(list_class, env->FindClass("java/util/List"));
     239               6 :     CHECK(list_iterator, env->GetMethodID(list_class, "iterator", "()Ljava/util/Iterator;"));
     240                 : 
     241               6 :     CHECK(set_class, env->FindClass("java/util/Set"));
     242               6 :     CHECK(set_iterator, env->GetMethodID(set_class, "iterator", "()Ljava/util/Iterator;"));
     243                 : 
     244               6 :     CHECK(map_class, env->FindClass("java/util/Map"));
     245               6 :     CHECK(map_get, env->GetMethodID(map_class, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"));
     246                 : 
     247               6 :     CHECK(iterator_class,  env->FindClass("java/util/Iterator"));
     248               6 :     CHECK(iterator_hasNext, env->GetMethodID(iterator_class, "hasNext", "()Z"));
     249               6 :     CHECK(iterator_next, env->GetMethodID(iterator_class, "next", "()Ljava/lang/Object;"));
     250                 : 
     251               6 :     CHECK(object_class,  env->FindClass("java/lang/Object"));
     252               6 :     CHECK(object_toString, env->GetMethodID(object_class, "toString", "()Ljava/lang/String;"));
     253               6 :     CHECK(object_getClass, env->GetMethodID(object_class, "getClass", "()Ljava/lang/Class;"));
     254                 : 
     255               6 :     CHECK(boolean_class,  env->FindClass("java/lang/Boolean"));
     256               6 :     CHECK(boolean_booleanValue, env->GetMethodID(boolean_class, "booleanValue", "()Z"));
     257                 : 
     258               6 :     CHECK(byte_class,  env->FindClass("java/lang/Byte"));
     259               6 :     CHECK(byte_byteValue, env->GetMethodID(byte_class, "byteValue", "()B"));
     260                 : 
     261               6 :     CHECK(short_class,  env->FindClass("java/lang/Short"));
     262               6 :     CHECK(short_shortValue, env->GetMethodID(short_class, "shortValue", "()S"));
     263                 : 
     264               6 :     CHECK(integer_class,  env->FindClass("java/lang/Integer"));
     265               6 :     CHECK(integer_intValue, env->GetMethodID(integer_class, "intValue", "()I"));
     266                 : 
     267               6 :     CHECK(float_class,  env->FindClass("java/lang/Float"));
     268               6 :     CHECK(float_floatValue, env->GetMethodID(float_class, "floatValue", "()F"));
     269                 : 
     270               6 :     CHECK(double_class,  env->FindClass("java/lang/Double"));
     271               6 :     CHECK(double_doubleValue, env->GetMethodID(integer_class, "doubleValue", "()D"));
     272                 : 
     273               6 :     return TRUE;
     274                 : }
     275                 : 
     276                 : 
     277                 : /************************************************************************/
     278                 : /*                       ExceptionOccured()                             */
     279                 : /************************************************************************/
     280                 : 
     281         5199898 : int OGRMDBJavaEnv::ExceptionOccured()
     282                 : {
     283         5199898 :     jthrowable exc = env->ExceptionOccurred();
     284         5199898 :     if (exc)
     285                 :     {
     286               0 :          env->ExceptionDescribe();
     287               0 :          env->ExceptionClear();
     288               0 :          return TRUE;
     289                 :     }
     290         5199898 :     return FALSE;
     291                 : }
     292                 : 
     293                 : 
     294                 : /************************************************************************/
     295                 : /*                           OGRMDBDatabase()                           */
     296                 : /************************************************************************/
     297                 : 
     298               6 : OGRMDBDatabase::OGRMDBDatabase()
     299                 : {
     300               6 :     env = NULL;
     301               6 :     database = NULL;
     302               6 : }
     303                 : 
     304                 : /************************************************************************/
     305                 : /*                          ~OGRMDBDatabase()                           */
     306                 : /************************************************************************/
     307                 : 
     308               6 : OGRMDBDatabase::~OGRMDBDatabase()
     309                 : {
     310               6 :     if (database)
     311                 :     {
     312               6 :         CPLDebug("MDB", "Closing database");
     313               6 :         env->env->CallVoidMethod(database, env->database_close);
     314                 : 
     315               6 :         env->env->DeleteGlobalRef(database);
     316                 :     }
     317               6 : }
     318                 : 
     319                 : /************************************************************************/
     320                 : /*                               Open()                                 */
     321                 : /************************************************************************/
     322                 : 
     323               6 : OGRMDBDatabase* OGRMDBDatabase::Open(OGRMDBJavaEnv* env, const char* pszName)
     324                 : {
     325               6 :     jstring jstr = env->env->NewStringUTF(pszName);
     326               6 :     jobject file = env->env->NewObject(env->file_class, env->file_constructor, jstr);
     327               6 :     if (env->ExceptionOccured()) return NULL;
     328               6 :     env->env->ReleaseStringUTFChars(jstr, NULL);
     329                 : 
     330               6 :     jobject database = env->env->CallStaticObjectMethod(env->database_class, env->database_open, file, JNI_TRUE);
     331                 : 
     332               6 :     env->env->DeleteLocalRef(file);
     333                 : 
     334               6 :     if (env->ExceptionOccured()) return NULL;
     335               6 :     if (database == NULL)
     336               0 :         return NULL;
     337                 : 
     338               6 :     OGRMDBDatabase* poDB = new OGRMDBDatabase();
     339               6 :     poDB->env = env;
     340               6 :     poDB->database = env->env->NewGlobalRef(database);
     341               6 :     env->env->DeleteLocalRef(database);
     342               6 :     return poDB;
     343                 : }
     344                 : 
     345                 : /************************************************************************/
     346                 : /*                        FetchTableNames()                             */
     347                 : /************************************************************************/
     348                 : 
     349               6 : int OGRMDBDatabase::FetchTableNames()
     350                 : {
     351               6 :     if (env->bCalledFromJava)
     352               0 :         env->Init();
     353                 : 
     354               6 :     jobject table_set = env->env->CallObjectMethod(database, env->database_getTableNames);
     355               6 :     if (env->ExceptionOccured()) return FALSE;
     356               6 :     jobject iterator = env->env->CallObjectMethod(table_set, env->set_iterator);
     357               6 :     if (env->ExceptionOccured()) return FALSE;
     358                 : 
     359             240 :     while( env->env->CallBooleanMethod(iterator, env->iterator_hasNext) )
     360                 :     {
     361             228 :         if (env->ExceptionOccured()) return FALSE;
     362             228 :         jstring table_name_jstring = (jstring) env->env->CallObjectMethod(iterator, env->iterator_next);
     363             228 :         if (env->ExceptionOccured()) return FALSE;
     364                 :         jboolean is_copy;
     365             228 :         const char* table_name_str = env->env->GetStringUTFChars(table_name_jstring, &is_copy);
     366                 : 
     367             228 :         apoTableNames.push_back(table_name_str);
     368                 :         //CPLDebug("MDB", "Table %s", table_name_str);
     369                 : 
     370             228 :         env->env->ReleaseStringUTFChars(table_name_jstring, table_name_str);
     371             228 :         env->env->DeleteLocalRef(table_name_jstring);
     372                 :     }
     373               6 :     env->env->DeleteLocalRef(iterator);
     374               6 :     env->env->DeleteLocalRef(table_set);
     375               6 :     return TRUE;
     376                 : }
     377                 : 
     378                 : /************************************************************************/
     379                 : /*                            GetTable()                                */
     380                 : /************************************************************************/
     381                 : 
     382              44 : OGRMDBTable* OGRMDBDatabase::GetTable(const char* pszTableName)
     383                 : {
     384              44 :     if (env->bCalledFromJava)
     385               0 :         env->Init();
     386                 : 
     387              44 :     jstring table_name_jstring = env->env->NewStringUTF(pszTableName);
     388              44 :     jobject table = env->env->CallObjectMethod(database, env->database_getTable, table_name_jstring);
     389              44 :     if (env->ExceptionOccured()) return NULL;
     390              44 :     env->env->DeleteLocalRef(table_name_jstring);
     391                 : 
     392              44 :     if (!table)
     393               2 :         return NULL;
     394                 : 
     395              42 :     jobject global_table = env->env->NewGlobalRef(table);
     396              42 :     env->env->DeleteLocalRef(table);
     397              42 :     table = global_table;
     398                 : 
     399              42 :     OGRMDBTable* poTable = new OGRMDBTable(env, this, table, pszTableName);
     400              42 :     if (!poTable->FetchColumns())
     401                 :     {
     402               0 :         delete poTable;
     403               0 :         return NULL;
     404                 :     }
     405              42 :     return poTable;
     406                 : }
     407                 : 
     408                 : /************************************************************************/
     409                 : /*                           OGRMDBTable()                              */
     410                 : /************************************************************************/
     411                 : 
     412              42 : OGRMDBTable::OGRMDBTable(OGRMDBJavaEnv* env, OGRMDBDatabase* poDB, jobject table, const char* pszTableName )
     413                 : {
     414              42 :     this->env = env;
     415              42 :     this->poDB = poDB;
     416              42 :     this->table = table;
     417              42 :     osTableName = pszTableName;
     418              42 :     table_iterator_obj = NULL;
     419              42 :     row = NULL;
     420              42 : }
     421                 : 
     422                 : /************************************************************************/
     423                 : /*                          ~OGRMDBTable()                              */
     424                 : /************************************************************************/
     425                 : 
     426              42 : OGRMDBTable::~OGRMDBTable()
     427                 : {
     428              42 :     if (env)
     429                 :     {
     430                 :         //CPLDebug("MDB", "Freeing table %s", osTableName.c_str());
     431              42 :         if (env->bCalledFromJava)
     432               0 :             env->Init();
     433                 : 
     434                 :         int i;
     435             498 :         for(i=0;i<(int)apoColumnNameObjects.size();i++)
     436             456 :             env->env->DeleteGlobalRef(apoColumnNameObjects[i]);
     437                 : 
     438              42 :         env->env->DeleteGlobalRef(table_iterator_obj);
     439              42 :         env->env->DeleteGlobalRef(row);
     440              42 :         env->env->DeleteGlobalRef(table);
     441                 :     }
     442              42 : }
     443                 : 
     444                 : /************************************************************************/
     445                 : /*                          FetchColumns()                              */
     446                 : /************************************************************************/
     447                 : 
     448              42 : int OGRMDBTable::FetchColumns()
     449                 : {
     450              42 :     if (env->bCalledFromJava)
     451               0 :         env->Init();
     452                 : 
     453              42 :     jobject column_lists = env->env->CallObjectMethod(table, env->table_getColumns);
     454              42 :     if (env->ExceptionOccured()) return FALSE;
     455                 : 
     456              42 :     jobject iterator_cols = env->env->CallObjectMethod(column_lists, env->list_iterator);
     457              42 :     if (env->ExceptionOccured()) return FALSE;
     458                 : 
     459             540 :     while( env->env->CallBooleanMethod(iterator_cols, env->iterator_hasNext) )
     460                 :     {
     461             456 :         if (env->ExceptionOccured()) return FALSE;
     462                 : 
     463             456 :         jobject column = env->env->CallObjectMethod(iterator_cols, env->iterator_next);
     464             456 :         if (env->ExceptionOccured()) return FALSE;
     465                 : 
     466             456 :         jstring column_name_jstring = (jstring) env->env->CallObjectMethod(column, env->column_getName);
     467             456 :         if (env->ExceptionOccured()) return FALSE;
     468                 :         jboolean is_copy;
     469             456 :         const char* column_name_str = env->env->GetStringUTFChars(column_name_jstring, &is_copy);
     470             456 :         apoColumnNames.push_back(column_name_str);
     471             456 :         env->env->ReleaseStringUTFChars(column_name_jstring, column_name_str);
     472                 : 
     473             456 :         apoColumnNameObjects.push_back((jstring) env->env->NewGlobalRef(column_name_jstring));
     474             456 :         env->env->DeleteLocalRef(column_name_jstring);
     475                 : 
     476             456 :         jobject column_type = env->env->CallObjectMethod(column, env->column_getType);
     477             456 :         if (env->ExceptionOccured()) return FALSE;
     478             456 :         int type = env->env->CallByteMethod(column_type, env->datatype_getValue);
     479             456 :         if (env->ExceptionOccured()) return FALSE;
     480             456 :         apoColumnTypes.push_back(type);
     481                 : 
     482             456 :         int isvariablelength = env->env->CallBooleanMethod(column, env->column_isVariableLength);
     483             456 :         if (env->ExceptionOccured()) return FALSE;
     484             456 :         if (!isvariablelength)
     485                 :         {
     486             360 :             int length = env->env->CallShortMethod(column, env->column_getLength);
     487             360 :             if (env->ExceptionOccured()) return FALSE;
     488             360 :             apoColumnLengths.push_back(length);
     489                 :         }
     490                 :         else
     491              96 :             apoColumnLengths.push_back(0);
     492                 : 
     493                 :         //CPLDebug("MDB", "Column %s, type = %d", apoColumnNames[apoColumnNames.size()-1].c_str(), type);
     494                 : 
     495             456 :         env->env->DeleteLocalRef(column_type);
     496                 : 
     497             456 :         env->env->DeleteLocalRef(column);
     498                 :     }
     499              42 :     env->env->DeleteLocalRef(iterator_cols);
     500              42 :     env->env->DeleteLocalRef(column_lists);
     501                 : 
     502              42 :     return TRUE;
     503                 : }
     504                 : 
     505                 : /************************************************************************/
     506                 : /*                          ResetReading()                              */
     507                 : /************************************************************************/
     508                 : 
     509             145 : void OGRMDBTable::ResetReading()
     510                 : {
     511             145 :     if (env->bCalledFromJava)
     512               0 :         env->Init();
     513                 : 
     514             145 :     env->env->DeleteGlobalRef(table_iterator_obj);
     515             145 :     table_iterator_obj = NULL;
     516             145 :     env->env->DeleteGlobalRef(row);
     517             145 :     row = NULL;
     518             145 : }
     519                 : 
     520                 : /************************************************************************/
     521                 : /*                           GetNextRow()                               */
     522                 : /************************************************************************/
     523                 : 
     524          273598 : int OGRMDBTable::GetNextRow()
     525                 : {
     526          273598 :     if (env->bCalledFromJava)
     527               0 :         env->Init();
     528                 : 
     529          273598 :     if (table_iterator_obj == NULL)
     530                 :     {
     531             104 :         table_iterator_obj = env->env->CallObjectMethod(table, env->table_iterator);
     532             104 :         if (env->ExceptionOccured()) return FALSE;
     533             104 :         if (table_iterator_obj)
     534                 :         {
     535             104 :             jobject global_table_iterator_obj = env->env->NewGlobalRef(table_iterator_obj);
     536             104 :             env->env->DeleteLocalRef(table_iterator_obj);
     537             104 :             table_iterator_obj = global_table_iterator_obj;
     538                 :         }
     539                 :     }
     540          273598 :     if (table_iterator_obj == NULL)
     541               0 :         return FALSE;
     542                 : 
     543          273598 :     if (!env->env->CallBooleanMethod(table_iterator_obj, env->iterator_hasNext))
     544              60 :         return FALSE;
     545          273538 :     if (env->ExceptionOccured()) return FALSE;
     546                 : 
     547          273538 :     if (row)
     548                 :     {
     549          273434 :         env->env->DeleteGlobalRef(row);
     550          273434 :         row = NULL;
     551                 :     }
     552                 : 
     553          273538 :     row = env->env->CallObjectMethod(table_iterator_obj, env->iterator_next);
     554          273538 :     if (env->ExceptionOccured()) return FALSE;
     555          273538 :     if (row == NULL)
     556               0 :         return FALSE;
     557                 : 
     558          273538 :     jobject global_row = env->env->NewGlobalRef(row);
     559          273538 :     env->env->DeleteLocalRef(row);
     560          273538 :     row = global_row;
     561                 : 
     562          273538 :     return TRUE;
     563                 : }
     564                 : 
     565                 : /************************************************************************/
     566                 : /*                          GetColumnVal()                              */
     567                 : /************************************************************************/
     568                 : 
     569         2187746 : jobject OGRMDBTable::GetColumnVal(int iCol)
     570                 : {
     571         2187746 :     if (row == NULL)
     572               0 :         return NULL;
     573                 : 
     574         2187746 :     jobject val = env->env->CallObjectMethod(row, env->map_get, apoColumnNameObjects[iCol]);
     575         2187746 :     if (env->ExceptionOccured()) return NULL;
     576         2187746 :     return val;
     577                 : }
     578                 : 
     579                 : /************************************************************************/
     580                 : /*                        GetColumnAsString()                           */
     581                 : /************************************************************************/
     582                 : 
     583         1640598 : char* OGRMDBTable::GetColumnAsString(int iCol)
     584                 : {
     585         1640598 :     jobject val = GetColumnVal(iCol);
     586         1640598 :     if (!val) return NULL;
     587                 : 
     588         1640598 :     jstring val_jstring = (jstring) env->env->CallObjectMethod(val, env->object_toString);
     589         1640598 :     if (env->ExceptionOccured()) return NULL;
     590                 :     jboolean is_copy;
     591         1640598 :     const char* val_str = env->env->GetStringUTFChars(val_jstring, &is_copy);
     592         1640598 :     char* dup_str = (val_str) ? CPLStrdup(val_str) : NULL;
     593         1640598 :     env->env->ReleaseStringUTFChars(val_jstring, val_str);
     594         1640598 :     env->env->DeleteLocalRef(val_jstring);
     595                 : 
     596         1640598 :     env->env->DeleteLocalRef(val);
     597                 : 
     598         1640598 :     return dup_str;
     599                 : }
     600                 : 
     601                 : /************************************************************************/
     602                 : /*                          GetColumnAsInt()                            */
     603                 : /************************************************************************/
     604                 : 
     605          273574 : int OGRMDBTable::GetColumnAsInt(int iCol)
     606                 : {
     607          273574 :     jobject val = GetColumnVal(iCol);
     608          273574 :     if (!val) return 0;
     609                 : 
     610          273574 :     int int_val = 0;
     611          273574 :     if (apoColumnTypes[iCol] == MDB_Boolean)
     612              18 :         int_val = env->env->CallBooleanMethod(val, env->boolean_booleanValue);
     613          273556 :     else if (apoColumnTypes[iCol] == MDB_Byte)
     614               0 :         int_val = env->env->CallByteMethod(val, env->byte_byteValue);
     615          273556 :     else if (apoColumnTypes[iCol] == MDB_Short)
     616               0 :         int_val = env->env->CallShortMethod(val, env->short_shortValue);
     617          273556 :     else if (apoColumnTypes[iCol] == MDB_Int)
     618          273556 :         int_val = env->env->CallIntMethod(val, env->integer_intValue);
     619          273574 :     if (env->ExceptionOccured()) return 0;
     620                 : 
     621          273574 :     env->env->DeleteLocalRef(val);
     622                 : 
     623          273574 :     return int_val;
     624                 : }
     625                 : 
     626                 : /************************************************************************/
     627                 : /*                        GetColumnAsDouble()                           */
     628                 : /************************************************************************/
     629                 : 
     630              72 : double OGRMDBTable::GetColumnAsDouble(int iCol)
     631                 : {
     632              72 :     jobject val = GetColumnVal(iCol);
     633              72 :     if (!val) return 0;
     634                 : 
     635              72 :     double double_val = 0;
     636              72 :     if (apoColumnTypes[iCol] == MDB_Double)
     637              72 :         double_val = env->env->CallDoubleMethod(val, env->double_doubleValue);
     638               0 :     else if (apoColumnTypes[iCol] == MDB_Float)
     639               0 :         double_val = env->env->CallFloatMethod(val, env->float_floatValue);
     640              72 :     if (env->ExceptionOccured()) return 0;
     641                 : 
     642              72 :     env->env->DeleteLocalRef(val);
     643                 : 
     644              72 :     return double_val;
     645                 : }
     646                 : 
     647                 : /************************************************************************/
     648                 : /*                        GetColumnAsBinary()                           */
     649                 : /************************************************************************/
     650                 : 
     651          273502 : GByte* OGRMDBTable::GetColumnAsBinary(int iCol, int* pnBytes)
     652                 : {
     653          273502 :     *pnBytes = 0;
     654                 : 
     655          273502 :     jobject val = GetColumnVal(iCol);
     656          273502 :     if (!val) return NULL;
     657                 : 
     658          273502 :     if (!env->env->IsInstanceOf(val, env->byteArray_class))
     659               0 :         return NULL;
     660                 : 
     661          273502 :     jbyteArray byteArray = (jbyteArray) val;
     662          273502 :     *pnBytes = env->env->GetArrayLength(byteArray);
     663          273502 :     if (env->ExceptionOccured()) return NULL;
     664                 :     jboolean is_copy;
     665          273502 :     jbyte* elts = env->env->GetByteArrayElements(byteArray, &is_copy);
     666          273502 :     if (env->ExceptionOccured()) return NULL;
     667                 : 
     668          273502 :     GByte* pData = (GByte*)CPLMalloc(*pnBytes);
     669          273502 :     memcpy(pData, elts, *pnBytes);
     670                 : 
     671          273502 :     env->env->ReleaseByteArrayElements(byteArray, elts, JNI_ABORT);
     672                 : 
     673          273502 :     env->env->DeleteLocalRef(val);
     674                 : 
     675          273502 :     return pData;
     676                 : }
     677                 : 
     678                 : /************************************************************************/
     679                 : /*                              DumpTable()                             */
     680                 : /************************************************************************/
     681                 : 
     682               0 : void OGRMDBTable::DumpTable()
     683                 : {
     684               0 :     ResetReading();
     685               0 :     int iRow = 0;
     686               0 :     int nCols = apoColumnNames.size();
     687               0 :     while(GetNextRow())
     688                 :     {
     689               0 :         printf("Row = %d\n", iRow ++);
     690               0 :         for(int i=0;i<nCols;i++)
     691                 :         {
     692               0 :             printf("%s = ", apoColumnNames[i].c_str());
     693               0 :             if (apoColumnTypes[i] == MDB_Float ||
     694                 :                 apoColumnTypes[i] == MDB_Double)
     695                 :             {
     696               0 :                 printf("%.15f\n", GetColumnAsDouble(i));
     697                 :             }
     698               0 :             else if (apoColumnTypes[i] == MDB_Boolean ||
     699                 :                      apoColumnTypes[i] == MDB_Byte ||
     700                 :                      apoColumnTypes[i] == MDB_Short ||
     701                 :                      apoColumnTypes[i] == MDB_Int)
     702                 :             {
     703               0 :                 printf("%d\n", GetColumnAsInt(i));
     704                 :             }
     705               0 :             else if (apoColumnTypes[i] == MDB_Binary ||
     706                 :                      apoColumnTypes[i] == MDB_OLE)
     707                 :             {
     708                 :                 int nBytes;
     709               0 :                 GByte* pData = GetColumnAsBinary(i, &nBytes);
     710               0 :                 printf("(%d bytes)\n", nBytes);
     711               0 :                 CPLFree(pData);
     712                 :             }
     713                 :             else
     714                 :             {
     715               0 :                 char* val = GetColumnAsString(i);
     716               0 :                 printf("'%s'\n", val);
     717               0 :                 CPLFree(val);
     718                 :             }
     719                 :         }
     720                 :     }
     721               0 : }
     722                 : 
     723                 : /************************************************************************/
     724                 : /*                            GetColumnIndex()                          */
     725                 : /************************************************************************/
     726                 : 
     727          547112 : int OGRMDBTable::GetColumnIndex(const char* pszColName, int bEmitErrorIfNotFound)
     728                 : {
     729          547112 :     int nCols = apoColumnNames.size();
     730          547112 :     CPLString osColName(pszColName);
     731          547400 :     for(int i=0;i<nCols;i++)
     732                 :     {
     733          547400 :         if (apoColumnNames[i] == osColName)
     734          547112 :             return i;
     735                 :     }
     736               0 :     if (bEmitErrorIfNotFound)
     737               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Cannot find column %s", pszColName);
     738               0 :     return -1;
     739                 : }
     740                 : 
     741                 : /************************************************************************/
     742                 : /*                             GetRowCount()                            */
     743                 : /************************************************************************/
     744                 : 
     745              20 : int OGRMDBTable::GetRowCount()
     746                 : {
     747              20 :     if (env->bCalledFromJava)
     748               0 :         env->Init();
     749              20 :     int nRowCount = env->env->CallIntMethod(table, env->table_getRowCount);
     750              20 :     if (env->ExceptionOccured()) return 0;
     751              20 :     return nRowCount;
     752                 : }

Generated by: LCOV version 1.7