source: tags/cvs_2_svn/PGT/file_import.cxx

Last change on this file was 5309, checked in by westram, 16 years ago
  • replaced calls to GB_find with new find-functions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 KB
Line 
1// Copyright (c) 2004 - 2005 Kai Bader <baderk@in.tum.de>
2//
3// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
6// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
7// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
8// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9
10// CVS REVISION TAG  --  $Revision: 5309 $
11
12
13/****************************************************************************
14*  TODO
15*
16*  - THE CSV-IMPORT SHOULD DIFFER BETWEEN THE DATA TYPES
17*  - CR/LF MUST BE REMOVED FROM THE LAST COLUMN
18****************************************************************************/
19
20
21#include <cstdio>
22#include <cstdlib>
23#include <iostream>
24#include <fstream>
25//
26#include <sys/types.h>
27#include <dirent.h>
28
29using namespace std;
30
31#include "file_import.hxx"
32
33
34/****************************************************************************
35*  IMPORT FUNCTION FOR A CSV DATA FILE (OPENS THE FILE AND RETURNS THE DATA)
36****************************************************************************/
37importTable *fileopenCSV(char *filename, int delimiter)
38{
39    // DEFINE VARIABLES
40    int inconsistencies= 0;
41    int rows=            0;
42    int total_columns=   0;
43    int local_columns=   0;
44    int cell_index;
45    int cell_size;
46    char **cells;
47    char *cell;
48    char *start_ptr;
49    char *end_ptr;
50
51    // ALLOCATE MEM FOR IMPORTTABLE STRUCTURE
52    importTable *table= NULL;
53
54//     // ALLOCATE MEM FOR IMPORTTABLE STRUCTURE
55//     importTable *table= (importTable *)malloc(sizeof(importTable));
56//     if(!table) return NULL;
57
58    // ALLOCATE MEMORY FOR READ BUFFER
59    char *buffer= (char *)malloc(sizeof(char) * 10241);
60    buffer[10240]=0;
61
62    // DEFINE INPUT STREAM AND OPEN FILE
63    ifstream iS;
64    iS.open(filename);
65
66    if(iS)
67    {
68        // PASS 1: GET CSV TABLE SIZE AND FIND INCONSISTENCIES
69
70        while(iS.getline(buffer, 10240))
71        {
72            rows++;
73            local_columns= 0;
74            start_ptr= buffer;
75
76            if(*start_ptr)
77            {
78                local_columns++;
79            }
80
81            while(*start_ptr && (end_ptr= strchr(start_ptr, delimiter)))
82            {
83                local_columns++;
84                start_ptr= end_ptr + 1;
85            }
86
87            if((local_columns != total_columns) && (rows > 1))
88            {
89                inconsistencies++;
90
91                printf("CSV-IMPORTER: found inconsistent data in row %d (%d instead of %d cells).\n",
92                       rows, local_columns, total_columns);
93            }
94            else
95            {
96                total_columns= local_columns;
97            }
98
99        }
100
101        // CHECK IF INCONSISTENCIES HAVE OCCURED AND ABORT IF NECESSARY
102        if(inconsistencies)
103        {
104            iS.close();
105            free(table);
106            free(buffer);
107            printf("CSV-IMPORTER: aborted due to inconsistent data (%d violations).\n", inconsistencies);
108            return NULL;
109        }
110
111        // PASS 2: READ CSV-DATA FROM FILE INTO THE MEM-ARRAY
112
113        // RESET FILE INPUT STREAM
114        iS.clear();
115        iS.seekg(0, ios::beg);
116
117
118
119        // ALLOCATE MEMORY FOR THE TABLE DATA
120        table= createImportTable(rows, total_columns);
121        if(!table) return NULL;
122
123//         cells= (char **)malloc(rows * total_columns * sizeof(char *));
124//         if(!cells)
125//         {
126//             iS.close();
127//             free(table);
128//             free(buffer);
129//             printf("CSV-IMPORTER: unable to allocate memory for the table data.\n");
130//             return NULL;
131//         }
132
133        cells= table->cell;
134//         table->rows= rows;
135//         table->columns= total_columns;
136
137        cell_index= 0;
138
139        while(iS.getline(buffer, 10240))
140        {
141            start_ptr= buffer;
142
143            while(*start_ptr && (end_ptr= strchr(start_ptr, delimiter)))
144            {
145                // REMOVE QUOTATION MARKS, IF NECESSARY
146                if(*start_ptr == '"' && *(end_ptr-1) == '"' && (start_ptr < (end_ptr-1)))
147                {
148                    start_ptr++;
149                    *(end_ptr-1)= 0;
150                }
151
152                cell_size= (int)(end_ptr - start_ptr) + 1;
153                cell= (char *)malloc(cell_size * sizeof(char));
154
155                *end_ptr= 0;
156                strncpy(cell, start_ptr, cell_size);
157
158                cells[cell_index]= cell;
159                cell_index++;
160
161                start_ptr= end_ptr + 1;
162            }
163            // if(*start_ptr)
164            //{
165                end_ptr= start_ptr;
166                while((*end_ptr) && (*end_ptr != 0x0D) && (*end_ptr != 0x0A)) end_ptr++;
167
168                cell_size= (int)(end_ptr - start_ptr) + 1;
169                cell= (char *)malloc(cell_size * sizeof(char));
170
171                *end_ptr= 0;
172                strncpy(cell, start_ptr, cell_size);
173
174                cells[cell_index]= cell;
175                cell_index++;
176            //}
177        }
178    }
179    else
180    {
181        // SOMETHING WENT WRONG. FREE ALLOCATED MEM AND RETURN
182        free(table);
183        free(buffer);
184        printf("CSV-IMPORTER: unable to open file: %s\n", filename);
185        return NULL;
186    }
187
188    iS.close();
189    free(buffer);
190
191    // IDENTIFY THE COLUMNS BEST FITTING DATATYPES
192    identifyColumns(table);
193
194    printf("CSV-IMPORTER: successfully imported file: %s (rows: %d, columns: %d)\n", filename, rows, total_columns);
195    return table;
196}
197
198
199/****************************************************************************
200*  IMPORT FUNCTION FOR CSV DATA & HEADER (IMPORTS DIRECTLY INTO ARB)
201****************************************************************************/
202int importCSV(importTable *table, importData *data)
203{
204    // FETCH ARB DATABASE HANDLE
205    GBDATA *gb_main= get_gbData();
206    GBDATA *gb_experiment;
207    GBDATA *gb_proteom, *gb_proteom_data, *gb_proteom_name;
208    GBDATA *gb_protein, *gb_protein_data, *gb_protein_entry;
209    char *head, *content;
210    int rows= table->rows;
211    int columns= table->columns;
212
213//     GBDATA *gb_main= get_gbData();
214//     GBDATA *gb_prot, *gb_exp, *gb_prot_data, *gb_prot_name;
215//     GBDATA *gb_protein, *gb_protein_entry;
216//     char *head, *content;
217//     int rows= table->rows;
218//     int columns= table->columns;
219    // CHECK IF AN ARB CONNECTION IS GIVEN
220    if(!gb_main)
221    {
222        printf("CSV import failed - no ARB connection.");
223        return -1;
224    }
225
226    // FIND EXPERIMENT ENTRY
227    gb_experiment= find_experiment(data->species, data->experiment);
228
229    // IF SO, EXIT THE FILE IMPORT (EVERYTHING OTHER WOULD LEAD TO INCONSISTENT DATA)
230    if(!gb_experiment)
231    {
232        printf("CSV import failed - the given species or experiment name could not be resolved.");
233        return -2;
234    }
235
236    // IS THERE ALREADY A PROTEOME WITH THE NEW FILENAME?
237    gb_proteom= find_proteome(gb_experiment, data->proteome);
238
239    // IF SO, EXIT THE FILE IMPORT (EVERYTHING OTHER WOULD LEAD TO INCONSISTENT DATA)
240    if(gb_proteom)
241    {
242        printf("CSV import failed - the given proteome name already exists (must be unique).");
243        return -3;
244    }
245
246    // BEGIN ARB TRANSACTION
247    ARB_begin_transaction();
248
249    // ENTER EXPERIMENT DATA ENTRY
250    gb_proteom_data= GB_entry(gb_experiment, "proteome_data");
251
252    // IF THERE IS NO PROETOME_DATA ENTRY, CREATE A NEW ONE
253    if(!gb_proteom_data) gb_proteom_data=
254        GB_create_container(gb_experiment, "proteome_data");
255
256    // CREATE NEW PROTEOME ENTRY
257    gb_proteom= GB_create_container(gb_proteom_data, "proteome");
258
259    // ADD THE NAME TO THE NEW PROTEOME ENTRY
260    gb_proteom_name= GB_create(gb_proteom, "name", GB_STRING);
261    GB_write_string(gb_proteom_name, data->proteome);
262
263    // CREATE PROTEINE DATA ENTRY
264    gb_protein_data= GB_create_container(gb_proteom, "proteine_data");
265
266    // IMPORT CELL DATA
267    for(int r= 1; r < rows; r++)
268    {
269        // EACH ROW REPRESENTS A PROTEIN -> NEW CONTAINER
270        gb_protein= GB_create_container(gb_protein_data, "protein");
271
272        // TRAVERSE COLUMNS FOR EACH ROW AND CREATE ENTRIES
273        for(int c= 0; c < columns; c++)
274        {
275            // CLEAN HEADER FOR USAGE AS ARB KEY
276            head= GBS_string_2_key(table->header[c]);
277
278            // FETCH CONTENT FOR THE NEW ENTRY
279            content= table->cell[(r * columns) + c];
280
281            // CHECK IF WE HAVE AN ENTRY
282            if(content)
283            {
284                // CHECK THE CORRECT COLUMN TYPE
285                if(table->hasTypes)
286                {
287                    switch(table->columnType[c])
288                    {
289                        case DATATYPE_INT:
290                            gb_protein_entry= GB_create(gb_protein, head, GB_INT);
291                            if(gb_protein_entry) GB_write_int(gb_protein_entry, atol(content));
292                            break;
293                        case DATATYPE_FLOAT:
294                            gb_protein_entry= GB_create(gb_protein, head, GB_FLOAT);
295                            if(gb_protein_entry) GB_write_float(gb_protein_entry, atof(content));
296                            break;
297                        default:
298                            gb_protein_entry= GB_create(gb_protein, head, GB_STRING);
299                            if(gb_protein_entry) GB_write_string(gb_protein_entry, content);
300                            break;
301                    }
302                }
303                else
304                {
305                    gb_protein_entry= GB_create(gb_protein, head, GB_STRING);
306                    GB_write_string(gb_protein_entry, content);
307                }
308            }
309        }
310    }
311
312    // END ARB TRANSACTION
313    ARB_commit_transaction();
314
315    return 0;
316}
317
318
319/****************************************************************************
320*  CREATE AN IMPORT TABLE
321****************************************************************************/
322importTable *createImportTable(int rows, int columns)
323{
324    // ALLOCATE MEMORY FOR THE TABLE DATA
325    importTable *table= (importTable *)malloc(sizeof(importTable));
326    if(!table) return NULL;
327
328    // ALLOCATE MEMORY FOR THE CELL DATA
329    char **cells= (char **)malloc(rows * columns * sizeof(char *));
330    if(!cells) return NULL;
331
332    // ALLOCATE MEMORY FOR THE HEADER DATA
333    char **header= (char **)malloc(columns * sizeof(char *));
334    if(!header) return NULL;
335
336    // INIT ALL CELL VALUES WITH NULL
337    int i;
338    for(i= 0; i < (rows * columns); i++) cells[i]= NULL;
339    for(i= 0; i < columns; i++) header[i]= NULL;
340
341    // ALLOCATE MEMORY FOR THE COLUMN TYPE DATA
342    int *columnType= (int *)malloc(columns * sizeof(int));
343    if(!columnType) return NULL;
344
345    // ENTER VALID PREDEFINED VALUES (SHOULD BE CHANGED LATER)
346    table->rows= rows;
347    table->columns= columns;
348    table->cell= cells;
349    table->header= header;
350    table->hasHeader= false;
351    table->columnType= columnType;
352
353    // RETURN POINTER TO TABLE
354    return table;
355}
356
357
358/****************************************************************************
359*  FIND XSLT FILES (*.XSL) AS IMPORT FILTERS
360****************************************************************************/
361XSLTimporter *findXSLTFiles(char *path)
362{
363    DIR *dir;
364    struct dirent *dir_entry;
365    int count= 0;
366    char *name;
367
368    // *** FIRST RUN, COUNT ENTRIES...
369
370    // EXIT, IF THE GIVEN PATH WAS INCORRECT
371    if((dir= opendir(path)) == NULL) return NULL;
372
373    // TRAVERSE ALL FILES...
374    while((dir_entry= readdir(dir)) != NULL)
375        if(strstr(dir_entry->d_name, ".xsl") || strstr(dir_entry->d_name, ".XSL"))
376            count++;
377
378    // CLOSE DIRECTORY HANDLE
379    closedir(dir);
380
381    // *** SECOND RUN, ALLOCATE SPACE AND READ ALL NAMES
382
383    // CREATE NEW STRUCT
384    XSLTimporter *xslt= (XSLTimporter *)malloc(sizeof(XSLTimporter));
385
386    // CREATE PATH ENTRY
387    xslt->path= (char *)malloc(sizeof(char) * (strlen(path) + 1));
388    strcpy(xslt->path, path);
389
390    // ALLOCATE MEM FOR NAME ARRAY POINTER
391    xslt->importer= (char **)malloc(sizeof(char *) * count);
392
393    // EXIT, IF THE GIVEN PATH WAS INCORRECT
394    if((dir= opendir(path)) == NULL)
395    {
396        free(xslt->importer);
397        free(xslt->path);
398        free(xslt);
399
400        return NULL;
401    }
402
403    // TRAVERSE ALL FILES...
404    count= 0;
405    while((dir_entry= readdir(dir)) != NULL)
406    {
407        if(strstr(dir_entry->d_name, ".xsl") || strstr(dir_entry->d_name, ".XSL"))
408        {
409            name= (char *)malloc(sizeof(char) * (strlen(dir_entry->d_name) + 1));
410            strcpy(name, dir_entry->d_name);
411
412            xslt->importer[count]= name;
413            count++;
414        }
415    }
416
417    xslt->number= count;
418
419    return xslt;
420}
421
422
423/****************************************************************************
424*  IDENTIFY ENTRY TYPE
425*  THIS FUNCTION TRIES TO IDENTIFY THE TYPE OF AN ENTRY (STRING, NUMBER)
426****************************************************************************/
427int identifyType(char *entry)
428{
429    bool has_dot= false;
430    bool has_numeric= true;
431    char *ptr= entry;
432
433    if(!ptr || (*ptr == 0)) return DATATYPE_UNKNOWN;
434
435    while(*ptr)
436    {
437        if((*ptr == '.') || (*ptr == ',')) has_dot= true;
438        else if((*ptr < '0') || (*ptr > '9')) has_numeric= false;
439
440        ptr++;
441    }
442
443    if(has_dot && has_numeric) return DATATYPE_FLOAT;
444    else if(has_numeric) return DATATYPE_INT;
445
446    return DATATYPE_STRING;
447}
448
449
450/****************************************************************************
451*  TRY TO IDENTIFY THE COLUMN TYPE USING THEIR ENTRIES
452****************************************************************************/
453void identifyColumns(importTable *table)
454{
455    // FUNCTION VARIABLES
456    int rows= table->rows;
457    int columns= table->columns;
458    char **cell= table->cell;
459    int *columnType= table->columnType;
460    int c, r, colType, cellType;
461
462    // TRAVERSE EVERY COLUMN
463    for(c= 0; c < columns; c++)
464    {
465        colType= DATATYPE_UNKNOWN;
466
467        // VIEW ALL ENTRIES AND IDENTIFY THE BEST FITTING TYPE
468        for(r= 1; r < rows; r++)
469        {
470            // GET THE CELLS DATATYPE
471            cellType= identifyType(cell[(r * columns) + c]);
472
473            // CHANGE COLUMN TYPE IF A HIGHER DATATYPE IS FOUND
474            if(cellType > colType) colType= cellType;
475
476//            // DEBUG DEBUG DEBUG
477//             if(cellType > colType)
478//             {
479//                 printf("COLUMN %d: ENTRY \'%s\' SWITCHED FROM %d TO %d\n",
480//                        c, cell[(r * columns) + c], colType, cellType);
481//                 colType= cellType;
482//             }
483//            // DEBUG DEBUG DEBUG
484}
485
486        columnType[c]= colType;
487    }
488}
489
490
491
492
Note: See TracBrowser for help on using the repository browser.