COOPY » Guide
version 0.6.5
|
00001 #include <coopy/Dbg.h> 00002 #include <coopy/AccessSheet.h> 00003 00004 #include "mdbtools.h" 00005 00006 using namespace coopy::store; 00007 using namespace coopy::store::mdb; 00008 using namespace std; 00009 00010 namespace coopy { 00011 namespace store { 00012 class AccessSchema; 00013 } 00014 } 00015 00016 #define DB(x) ((MdbHandle *)(x)) 00017 #define TABLE(x) ((MdbTableDef *)(x)) 00018 00019 AccessSheet::AccessSheet(void *db1, const char *name, const Property& config) { 00020 implementation = db1; 00021 table_implementation = NULL; 00022 this->name = name; 00023 this->config = config; 00024 w = h = 0; 00025 00026 schema = new AccessSheetSchema; 00027 COOPY_MEMORY(schema); 00028 schema->sheet = this; 00029 } 00030 00031 bool AccessSheet::connect() { 00032 MdbHandle *mdb = DB(implementation); 00033 if (mdb==NULL) return false; 00034 00035 MdbTableDef *table = mdb_read_table_by_name(mdb, (char *)name.c_str(), 00036 MDB_TABLE); 00037 if (!table) return false; 00038 table_implementation = table; 00039 mdb_read_columns(table); 00040 mdb_read_indices(table); 00041 mdb_rewind_table(table); 00042 00044 // Check dimensions 00045 00046 h = (int)table->num_rows; 00047 w = (int)table->num_cols; 00048 00050 // Check column names 00051 00052 for (int j=0; j<table->num_cols; j++) { 00053 MdbColumn *col=(MdbColumn *)g_ptr_array_index(table->columns,j); 00054 col2sql.push_back(col->name); 00055 col2pk.push_back(false); 00056 char *kind = mdb_get_coltype_string(mdb->default_backend, col->col_type); 00057 col2type.push_back(kind); 00058 } 00059 00061 // Check keys 00062 00063 if (config.flag("indexes",false)) { 00064 for (int i=0;i<table->num_idxs;i++) { 00065 MdbIndex *idx = (MdbIndex *)g_ptr_array_index(table->indices,i); 00066 if (idx->index_type==1) { 00067 for (int j=0;j<idx->num_keys;j++) { 00068 int off = idx->key_col_num[j]-1; 00069 col2pk[off] = true; 00070 } 00071 } 00072 } 00073 } 00074 00076 // Cache data - haven't figured out random access yet 00077 00078 cache.resize(w,h,""); 00079 cacheFlag.resize(w,h,0); 00080 00081 char **bound_values = (char **)g_malloc(table->num_cols * sizeof(char *)); 00082 int *bound_lens = (int *)g_malloc(table->num_cols * sizeof(int)); 00083 for (int j=0;j<table->num_cols;j++) { 00084 bound_values[j] = (char *) g_malloc0(MDB_BIND_SIZE); 00085 mdb_bind_column(table, j+1, bound_values[j], &bound_lens[j]); 00086 } 00087 int at = 0; 00088 while(mdb_fetch_row(table)) { 00089 for (int j=0;j<table->num_cols;j++) { 00090 MdbColumn *col=(MdbColumn *)g_ptr_array_index(table->columns,j); 00091 bool ole = false; 00092 if ((col->col_type == MDB_OLE) 00093 && ((j==0) || (col->cur_value_len))) { 00094 ole = true; 00095 } 00096 string val; 00097 bool escaped; 00098 if (ole) { 00099 val = "<MEDIA>"; 00100 escaped = true; 00101 } else if (!bound_lens[j]) { 00102 val = "NULL"; 00103 escaped = true; 00104 } else { 00105 val = bound_values[j]; 00106 escaped = false; 00107 } 00108 //printf("Got %d %d -> %s\n", j, at, val.c_str()); 00109 cache.cell(j,at) = val; 00110 if (escaped) { 00111 cacheFlag.cell(j,at) = escaped?1:0; 00112 } 00113 } 00114 at++; 00115 } 00116 for (int j=0;j<table->num_cols;j++) { 00117 g_free(bound_values[j]); 00118 } 00119 g_free(bound_values); 00120 g_free(bound_lens); 00121 00122 return true; 00123 } 00124 00125 AccessSheet::~AccessSheet() { 00126 if (table_implementation!=NULL) { 00127 mdb_free_tabledef(TABLE(table_implementation)); 00128 table_implementation = NULL; 00129 } 00130 if (schema!=NULL) delete schema; 00131 schema = NULL; 00132 } 00133 00134 SheetSchema *AccessSheet::getSchema() const { 00135 return schema; 00136 } 00137 00138 00139 std::string AccessSheet::cellString(int x, int y) const { 00140 bool tmp; 00141 return cellString(x,y,tmp); 00142 } 00143 00144 std::string AccessSheet::cellString(int x, int y, bool& escaped) const { 00145 escaped = false; 00146 const unsigned char *f = cacheFlag.pcell_const(x,y); 00147 if (f!=NULL) { 00148 escaped = true; 00149 return "NULL"; 00150 } 00151 const string *c = cache.pcell_const(x,y); 00152 if (c!=NULL) { 00153 return *c; 00154 } 00155 00156 escaped = true; 00157 return ""; 00158 } 00159