Annotation of parser3/src/types/pa_vtable.C, revision 1.46
1.1 parser 1: /** @file
2: Parser: @b table class.
3:
1.43 moko 4: Copyright (c) 2001-2015 Art. Lebedev Studio (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:
8: #include "pa_vtable.h"
9: #include "pa_vstring.h"
1.5 parser 10: #include "pa_vhash.h"
1.22 paf 11: #include "pa_vvoid.h"
1.46 ! moko 12: #include "pa_request.h"
1.1 parser 13:
1.46 ! moko 14: volatile const char * IDENT_PA_VTABLE_C="$Id: pa_vtable.C,v 1.45 2016/05/24 17:48:38 moko Exp $" IDENT_PA_VTABLE_H;
1.37 moko 15:
1.3 parser 16: #ifndef DOXYGEN
1.1 parser 17: struct Record_info {
1.22 paf 18: Table* table;
19: HashStringValue* hash;
1.1 parser 20: };
1.3 parser 21: #endif
1.29 misha 22:
23: static void store_column_item_to_hash(const String* column_name, Record_info *info) {
24: const String* column_item=info->table->item(*column_name);
1.45 moko 25: info->hash->put(*column_name, (column_item && !column_item->is_empty()) ? new VString(*column_item) : new VString() );
1.1 parser 26: }
1.29 misha 27:
1.22 paf 28: Value* VTable::fields_element() {
1.29 misha 29: Value& result=*new VHash;
1.22 paf 30: Table& ltable=table();
1.29 misha 31: if(!ltable.count())
32: return &result;
33:
34: HashStringValue* hash=result.get_hash();
35:
36: if(Table::columns_type columns=ltable.columns()) { // named
37: Record_info record_info={<able, hash};
1.1 parser 38: columns->for_each(store_column_item_to_hash, &record_info);
1.29 misha 39: } else { // nameless
40: size_t row_size=ltable[ltable.current()]->count(); // number of columns in current row
41: for(size_t index=0; index<row_size; index++){
42: const String* column_item=ltable.item(index);
43: hash->put(String::Body::Format(index),
44: (column_item && !column_item->is_empty())
45: ?new VString(*column_item)
46: :new VString()
47: );
48: }
1.1 parser 49: }
1.29 misha 50:
51: return &result;
1.1 parser 52: }
53:
1.31 misha 54: Value* VTable::get_element(const String& aname) {
1.1 parser 55: // fields
1.45 moko 56: if(SYMBOLS_EQ(aname,FIELDS_SYMBOL))
1.1 parser 57: return fields_element();
58:
1.44 moko 59: #ifdef FEATURE_GET_ELEMENT4CALL
1.40 moko 60: // columns first
61: if(ftable) {
62: int index=ftable->column_name2index(aname, false);
63: if(index>=0) // column aname|number valid
64: {
65: const String* string=ftable->item(index); // there is such column
66: return new VString(string ? *string : String::Empty);
67: }
68: }
69:
1.42 moko 70: #ifndef OPTIMIZE_BYTECODE_GET_ELEMENT__SPECIAL
1.44 moko 71: // CLASS, CLASS_NAME
1.31 misha 72: if(Value* result=VStateless_object::get_element(aname))
1.2 parser 73: return result;
1.42 moko 74: #endif
1.2 parser 75:
1.40 moko 76: throw Exception(PARSER_RUNTIME, &aname, "column not found");
77: }
78:
79: Value* VTable::get_element4call(const String& aname) {
1.44 moko 80: // methods
81: return VStateless_object::get_element(aname);
82: }
1.40 moko 83:
1.44 moko 84: #else
1.40 moko 85: // methods first
86: if(Value* result=VStateless_object::get_element(aname))
87: return result;
88:
1.1 parser 89: // columns
90: if(ftable) {
1.16 paf 91: int index=ftable->column_name2index(aname, false);
92: if(index>=0) // column aname|number valid
1.32 pretende 93: {
94: const String* string=ftable->item(index); // there is such column
95: return new VString(string ? *string : String::Empty);
96: }
1.1 parser 97: }
98:
1.39 moko 99: throw Exception(PARSER_RUNTIME, &aname, "column not found");
1.1 parser 100: }
1.44 moko 101: #endif
1.33 misha 102:
1.39 moko 103: const VJunction* VTable::put_element(const String& aname, Value* avalue) {
104: if(ftable) {
105: int index=ftable->column_name2index(aname, false);
106: if(index>=0) // column aname|number valid
107: {
1.46 ! moko 108: if(index > pa_loop_limit)
1.39 moko 109: throw Exception(PARSER_RUNTIME, &aname, "too big column number");
110: if(!avalue->is_string())
111: throw Exception(PARSER_RUNTIME, 0, "column value must be string");
112: ftable->put_item(index, avalue->get_string());
113: return PUT_ELEMENT_REPLACED_ELEMENT;
114: }
115: }
116:
117: throw Exception(PARSER_RUNTIME, &aname, "column not found");
118: }
1.36 moko 119:
120: String& VTable::get_json_string_array(String& result, const char *indent) {
121: // [
122: // ["c1", "c2", "c3" ...] || null (for nameless),
123: // ["v11", "v12", "v13" ...],
124: // ["v21", "v22", "v23" ...],
125: // ...
126: // ]
1.33 misha 127: Table& ltable=table();
1.35 moko 128:
1.36 moko 129: // columns
130: if(ltable.columns()){
131: // named
132: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
133:
134: bool need_delim=false;
135: for(Array_iterator<const String*> c(*ltable.columns()); c.has_next(); ) {
136: if(need_delim)
137: result << "\",\"";
138: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
139: need_delim=true;
140: }
141: result << "\"]";
142: } else {
143: // nameless
144: indent ? result << "\n\t" << indent << "null" : result << "\nnull";
145: }
146:
147: // data
148: if(ltable.count()){
149: result << ",";
150: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
151: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
1.33 misha 152: bool need_delim=false;
1.36 moko 153: for(Array_iterator<const String*> c(*r.next()); c.has_next(); ) {
1.33 misha 154: if(need_delim)
155: result << "\",\"";
156: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
157: need_delim=true;
158: }
1.36 moko 159: r.has_next() ? result << "\"]," : result << "\"]";
1.35 moko 160: }
1.36 moko 161: }
162:
163: result << "\n" << indent;
164: return result;
165: }
166:
167: String& VTable::get_json_string_object(String& result, const char *indent) {
168: // [
169: // {"c1":"v11", "c2":"v12", "c3":"v13"},
170: // {"c1":"v21", "c2":"v22", "c3":"v23"},
171: // ...
172: // ]
173: Table& ltable=table();
174: ArrayString* columns=ltable.columns();
175: size_t columns_count = (columns) ? columns->count() : 0;
176:
177: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
178: indent ? result << "\n\t" << indent << "{\"" : result << "\n{\"";
1.33 misha 179:
1.36 moko 180: ArrayString* row=r.next();
181: for(size_t index=0; index<row->count(); index++){
182: if(index)
183: result << "\",\"";
184: result.append(index < columns_count ? *columns->get(index) : String(format(index, 0)), String::L_JSON, true/*forced lang*/);
185: result << "\":\"";
186: result.append(*row->get(index), String::L_JSON, true/*forced lang*/);
1.33 misha 187: }
1.36 moko 188: r.has_next() ? result << "\"}," : result << "\"}\n" << indent;
189: }
190: return result;
191: }
192:
193: String& VTable::get_json_string_compact(String& result, const char *indent) {
194: // [
195: // "v11",
196: // ["v21", "v22", "v23" ...],
197: // ...
198: // ]
199: Table& ltable=table();
200:
201: for(Array_iterator<ArrayString*> r(ltable); r.has_next(); ) {
202: ArrayString& line=*r.next();
203: if (line.count()==1){
204: indent ? result << "\n\t" << indent << "\"" : result << "\n\"";
1.33 misha 205:
1.36 moko 206: result.append(*line[0], String::L_JSON, true/*forced lang*/);
207: r.has_next() ? result << "\"," : result << "\"\n" << indent;
208: } else {
209: indent ? result << "\n\t" << indent << "[\"" : result << "\n[\"";
1.33 misha 210:
1.36 moko 211: bool need_delim=false;
212: for(Array_iterator<const String*> c(line); c.has_next(); ) {
213: if(need_delim)
1.33 misha 214: result << "\",\"";
1.36 moko 215: result.append(*c.next(), String::L_JSON, true/*forced lang*/);
216: need_delim=true;
1.33 misha 217: }
1.36 moko 218: r.has_next() ? result << "\"]," : result << "\"]\n" << indent;
219: }
220: }
221: return result;
222: }
223:
1.38 moko 224: const String* VTable::get_json_string(Json_options& options) {
1.36 moko 225: String* result = new String("[", String::L_AS_IS);
1.33 misha 226:
1.38 moko 227: switch(options.table){
1.36 moko 228: case Json_options::T_ARRAY:
1.38 moko 229: result=&get_json_string_array(*result, options.indent);
1.36 moko 230: break;
231: case Json_options::T_OBJECT:
1.38 moko 232: result=&get_json_string_object(*result, options.indent);
1.36 moko 233: break;
234: case Json_options::T_COMPACT:
1.38 moko 235: result=&get_json_string_compact(*result, options.indent);
1.36 moko 236: break;
1.33 misha 237: }
238:
1.36 moko 239: *result << "]";
240: return result;
241: }
E-mail: