Annotation of parser3/src/types/pa_vtable.C, revision 1.36

1.1       parser      1: /** @file
                      2:        Parser: @b table class.
                      3: 
1.28      misha       4:        Copyright(c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com)
1.11      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.14      paf         6: */
1.1       parser      7: 
1.36    ! moko        8: static const char * const IDENT_VTABLE_C="$Date: 2010-09-24 08:18:57 $";
1.1       parser      9: 
                     10: #include "pa_vtable.h"
                     11: #include "pa_vstring.h"
1.5       parser     12: #include "pa_vhash.h"
1.22      paf        13: #include "pa_vvoid.h"
1.1       parser     14: 
1.3       parser     15: #ifndef DOXYGEN
1.1       parser     16: struct Record_info {
1.22      paf        17:        Table* table;
                     18:        HashStringValue* hash;
1.1       parser     19: };
1.3       parser     20: #endif
1.29      misha      21: 
                     22: static void store_column_item_to_hash(const String* column_name, Record_info *info) {
                     23:        const String* column_item=info->table->item(*column_name);
                     24:        info->hash->put(*column_name, 
                     25:                (column_item && !column_item->is_empty())
                     26:                        ?new VString(*column_item)
                     27:                        :new VString()
                     28:        );
1.1       parser     29: }
1.29      misha      30: 
1.22      paf        31: Value* VTable::fields_element() {
1.29      misha      32:        Value& result=*new VHash;
1.22      paf        33:        Table& ltable=table();
1.29      misha      34:        if(!ltable.count())
                     35:                return &result;
                     36: 
                     37:        HashStringValue* hash=result.get_hash();
                     38: 
                     39:        if(Table::columns_type columns=ltable.columns()) { // named
                     40:                Record_info record_info={&ltable, hash};
1.1       parser     41:                columns->for_each(store_column_item_to_hash, &record_info);
1.29      misha      42:        } else { // nameless
                     43:                size_t row_size=ltable[ltable.current()]->count(); // number of columns in current row
                     44:                for(size_t index=0; index<row_size; index++){
                     45:                        const String* column_item=ltable.item(index);
                     46:                        hash->put(String::Body::Format(index), 
                     47:                                (column_item && !column_item->is_empty())
                     48:                                        ?new VString(*column_item)
                     49:                                        :new VString()
                     50:                        );
                     51:                }
1.1       parser     52:        }
1.29      misha      53: 
                     54:        return &result;
1.1       parser     55: }
                     56: 
1.31      misha      57: Value* VTable::get_element(const String& aname) {
1.1       parser     58:        // fields
1.16      paf        59:        if(aname==TABLE_FIELDS_ELEMENT_NAME)
1.1       parser     60:                return fields_element();
                     61: 
1.2       parser     62:        // methods
1.31      misha      63:        if(Value* result=VStateless_object::get_element(aname))
1.2       parser     64:                return result;
                     65: 
1.1       parser     66:        // columns
                     67:        if(ftable) {
1.16      paf        68:                int index=ftable->column_name2index(aname, false);
                     69:                if(index>=0) // column aname|number valid
1.32      pretende   70:                {
                     71:                        const String* string=ftable->item(index); // there is such column
                     72:                        return new VString(string ? *string : String::Empty);
                     73:                }
1.1       parser     74:        }
                     75: 
1.27      misha      76:        throw Exception(PARSER_RUNTIME,
1.16      paf        77:                &aname, 
1.1       parser     78:                "column not found");
                     79: }
1.33      misha      80: 
1.36    ! moko       81: 
        !            82: String& VTable::get_json_string_array(String& result, const char *indent) {
        !            83:        // [
        !            84:        //              ["c1",  "c2",  "c3"  ...] || null (for nameless),
        !            85:        //              ["v11", "v12", "v13" ...],
        !            86:        //              ["v21", "v22", "v23" ...],
        !            87:        //              ...
        !            88:        // ]
1.33      misha      89:        Table& ltable=table();
1.35      moko       90: 
1.36    ! moko       91:        // columns
        !            92:        if(ltable.columns()){
        !            93:                // named
        !            94:                indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
        !            95: 
        !            96:                bool need_delim=false;
        !            97:                for(Array_iterator<const String*> c(*ltable.columns()); c.has_next(); ) {
        !            98:                        if(need_delim)
        !            99:                                result << "\",\"";
        !           100:                        result.append(*c.next(), String::L_JSON, true/*forced lang*/);
        !           101:                        need_delim=true;
        !           102:                }
        !           103:                result << "\"]";
        !           104:        } else {
        !           105:                // nameless
        !           106:                indent ? result << "\n\t" << indent << "null" : result << "\nnull";
        !           107:        }
        !           108: 
        !           109:        // data
        !           110:        if(ltable.count()){
        !           111:                result << ",";
        !           112:                for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
        !           113:                        indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
1.33      misha     114:                        bool need_delim=false;
1.36    ! moko      115:                        for(Array_iterator<const String*> c(*r.next()); c.has_next(); ) {
1.33      misha     116:                                if(need_delim)
                    117:                                        result << "\",\"";
                    118:                                result.append(*c.next(), String::L_JSON, true/*forced lang*/);
                    119:                                need_delim=true;
                    120:                        }
1.36    ! moko      121:                        r.has_next() ? result << "\"]," : result << "\"]";
1.35      moko      122:                }
1.36    ! moko      123:        }
        !           124: 
        !           125:        result << "\n" << indent; 
        !           126:        return result;
        !           127: }
        !           128: 
        !           129: String& VTable::get_json_string_object(String& result, const char *indent) {
        !           130:        // [
        !           131:        //              {"c1":"v11", "c2":"v12", "c3":"v13"},
        !           132:        //              {"c1":"v21", "c2":"v22", "c3":"v23"},
        !           133:        //              ...
        !           134:        // ]
        !           135:        Table& ltable=table();
        !           136:        ArrayString* columns=ltable.columns();
        !           137:        size_t columns_count = (columns) ? columns->count() : 0;
        !           138: 
        !           139:        for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
        !           140:                indent ? result << "\n\t" << indent << "{\"" : result << "\n{\"";
1.33      misha     141: 
1.36    ! moko      142:                ArrayString* row=r.next();
        !           143:                for(size_t index=0; index<row->count(); index++){
        !           144:                        if(index)
        !           145:                                result << "\",\"";
        !           146:                        result.append(index < columns_count ? *columns->get(index) : String(format(index, 0)), String::L_JSON, true/*forced lang*/);
        !           147:                        result << "\":\"";
        !           148:                        result.append(*row->get(index), String::L_JSON, true/*forced lang*/);
1.33      misha     149:                }
1.36    ! moko      150:                r.has_next() ? result << "\"}," : result << "\"}\n" << indent;
        !           151:        }
        !           152:        return result;
        !           153: }
        !           154: 
        !           155: String& VTable::get_json_string_compact(String& result, const char *indent) {
        !           156:        // [
        !           157:        //              "v11",
        !           158:        //              ["v21", "v22", "v23" ...],
        !           159:        //              ...
        !           160:        // ]
        !           161:        Table& ltable=table();
        !           162: 
        !           163:        for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
        !           164:                ArrayString& line=*r.next();
        !           165:                if (line.count()==1){
        !           166:                        indent ? result << "\n\t" << indent << "\"" : result << "\n\"";
1.33      misha     167: 
1.36    ! moko      168:                        result.append(*line[0], String::L_JSON, true/*forced lang*/);
        !           169:                        r.has_next() ? result << "\"," : result << "\"\n" << indent;
        !           170:                } else {
        !           171:                        indent ? result << "\n\t" << indent << "[\"" :  result << "\n[\"";
1.33      misha     172: 
1.36    ! moko      173:                        bool need_delim=false;
        !           174:                        for(Array_iterator<const String*> c(line); c.has_next(); ) {
        !           175:                                if(need_delim)
1.33      misha     176:                                        result << "\",\"";
1.36    ! moko      177:                                result.append(*c.next(), String::L_JSON, true/*forced lang*/);
        !           178:                                need_delim=true;
1.33      misha     179:                        }
1.36    ! moko      180:                        r.has_next() ? result << "\"]," : result  << "\"]\n" << indent;
        !           181:                }
        !           182:        }
        !           183:        return result;
        !           184: }
        !           185: 
        !           186: const String* VTable::get_json_string(Json_options* options) {
        !           187:        String* result = new String("[", String::L_AS_IS);
1.33      misha     188: 
1.36    ! moko      189:        switch(options->table){
        !           190:        case Json_options::T_ARRAY:
        !           191:                result=&get_json_string_array(*result, options->indent);
        !           192:                break;
        !           193:        case Json_options::T_OBJECT:
        !           194:                result=&get_json_string_object(*result, options->indent);
        !           195:                break;
        !           196:        case Json_options::T_COMPACT:
        !           197:                result=&get_json_string_compact(*result, options->indent);
        !           198:                break;
1.33      misha     199:        }
                    200: 
1.36    ! moko      201:        *result << "]";
        !           202:        return result;
        !           203: }

E-mail: