|
|
| version 1.166, 2002/10/23 09:32:17 | version 1.172.2.1, 2003/01/28 15:42:40 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: @b table parser class. | Parser: @b table parser class. |
| Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| Line 19 static const char* IDENT_TABLE_C="$Date$ | Line 19 static const char* IDENT_TABLE_C="$Date$ |
| class MTable : public Methoded { | class MTable : public Methoded { |
| public: // VStateless_class | public: // VStateless_class |
| Value *create_new_value(Pool& pool) { return new(pool) VTable(pool); } | ValuePtr create_new_value() { return ValuePtr(new VTable()); } |
| public: | public: |
| MTable(Pool& pool); | MTable(Pool& pool); |
| Line 125 static void _create(Request& r, const St | Line 125 static void _create(Request& r, const St |
| static void _load(Request& r, const String& method_name, MethodParams *params) { | static void _load(Request& r, const String& method_name, MethodParams *params) { |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| // filename is last parameter | const String& first_param=params->as_string(0, "file name must be string"); |
| Value& vfile_name=params->as_no_junction(params->size()-1, | int filename_param_index=0; |
| "file name must not be code"); | bool nameless=first_param=="nameless"; |
| if(nameless) | |
| filename_param_index++; | |
| int options_param_index=filename_param_index+1; | |
| // loading text | // loading text |
| char *data=file_read_text(pool, r.absolute(vfile_name.as_string())); | char *data=file_read_text(pool, |
| r.absolute(params->as_string(filename_param_index, "file name must be string")), | |
| true, | |
| options_param_index<params->size()?params->as_no_junction(options_param_index, "additional params must be hash").get_hash(&method_name):0 | |
| ); | |
| // parse columns | // parse columns |
| Array *columns; | Array *columns; |
| Line 139 static void _load(Request& r, const Stri | Line 146 static void _load(Request& r, const Stri |
| const char *file=origin.file; | const char *file=origin.file; |
| uint line=origin.line; | uint line=origin.line; |
| #endif | #endif |
| if(params->size()==2) { | if(nameless) { |
| columns=0; // nameless | columns=0; // nameless |
| } else { | } else { |
| columns=new(pool) Array(pool); | columns=new(pool) Array(pool); |
| Line 311 struct Row_info { | Line 318 struct Row_info { |
| Array *value_fields; | Array *value_fields; |
| Hash *hash; | Hash *hash; |
| bool distinct; | bool distinct; |
| int index; | int row; |
| }; | }; |
| #endif | #endif |
| static void table_row_to_hash(Array::Item *value, void *info) { | static void table_row_to_hash(Array::Item *value, void *info) { |
| Line 321 static void table_row_to_hash(Array::Ite | Line 328 static void table_row_to_hash(Array::Ite |
| const String *key; | const String *key; |
| if(ri.key_code) { | if(ri.key_code) { |
| ri.table->set_current(ri.index++); // change context row | ri.table->set_current(ri.row++); // change context row |
| StringOrValue sv_processed=ri.r->process(*ri.key_code); | StringOrValue sv_processed=ri.r->process(*ri.key_code); |
| key=&sv_processed.as_string(); | key=&sv_processed.as_string(); |
| } else | } else |
| Line 450 static void _sort(Request& r, const Stri | Line 457 static void _sort(Request& r, const Stri |
| // calculate key values | // calculate key values |
| bool key_values_are_strings=true; | bool key_values_are_strings=true; |
| // save 'current' | |
| int saved_current=old_table.current(); | |
| for(i=0; i<old_table.size(); i++) { | for(i=0; i<old_table.size(); i++) { |
| old_table.set_current(i); | old_table.set_current(i); |
| // calculate key value | // calculate key value |
| Line 465 static void _sort(Request& r, const Stri | Line 470 static void _sort(Request& r, const Stri |
| else | else |
| seq[i].value.d=value.as_double(); | seq[i].value.d=value.as_double(); |
| } | } |
| // restore 'current' | |
| old_table.set_current(saved_current); | |
| // sort keys | // sort keys |
| _qsort(seq, old_table.size(), sizeof(Table_seq_item), | _qsort(seq, old_table.size(), sizeof(Table_seq_item), |
| key_values_are_strings?sort_cmp_string:sort_cmp_double); | key_values_are_strings?sort_cmp_string:sort_cmp_double); |
| Line 594 static void _join(Request& r, const Stri | Line 597 static void _join(Request& r, const Stri |
| } | } |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| class Table_sql_event_handlers : public SQL_Driver_query_event_handlers { | class Table_sql_event_handlers: public SQL_Driver_query_event_handlers { |
| public: | public: |
| Table_sql_event_handlers(Pool& apool, const String& amethod_name, | Table_sql_event_handlers(Pool& apool, const String& amethod_name, |
| const String& astatement_string, const char *astatement_cstr) : | const String& astatement_string, const char *astatement_cstr) : |
| Line 608 public: | Line 611 public: |
| { | { |
| } | } |
| void add_column(void *ptr, size_t size) { | bool add_column(SQL_Error& error, void *ptr, size_t size) { |
| String *column=new(pool) String(pool); | try { |
| column->APPEND_TAINTED( | String *column=new(pool) String(pool); |
| (const char *)ptr, size, | column->APPEND_TAINTED( |
| statement_cstr, 0); | |
| columns+=column; | |
| } | |
| void before_rows() { | |
| table=new(pool) Table(pool, &method_name, &columns); | |
| } | |
| void add_row() { | |
| (*table)+=(row=new(pool) Array(pool)); | |
| } | |
| void add_row_cell(void *ptr, size_t size) { | |
| String *cell=new(pool) String(pool); | |
| if(size) | |
| cell->APPEND_TAINTED( | |
| (const char *)ptr, size, | (const char *)ptr, size, |
| statement_cstr, table->size()-1); | statement_cstr, 0); |
| (*row)+=cell; | columns+=column; |
| return false; | |
| } catch(...) { | |
| error=SQL_Error("exception occured in Table_sql_event_handlers::add_column"); | |
| return true; | |
| } | |
| } | |
| bool before_rows(SQL_Error& error) { | |
| try { | |
| table=new(pool) Table(pool, &method_name, &columns); | |
| return false; | |
| } catch(...) { | |
| error=SQL_Error("exception occured in Table_sql_event_handlers::before_rows"); | |
| return true; | |
| } | |
| } | |
| bool add_row(SQL_Error& error) { | |
| try { | |
| (*table)+=(row=new(pool) Array(pool)); | |
| return false; | |
| } catch(...) { | |
| error=SQL_Error("exception occured in Table_sql_event_handlers::add_row"); | |
| return true; | |
| } | |
| } | |
| bool add_row_cell(SQL_Error& error, void *ptr, size_t size) { | |
| try { | |
| String *cell=new(pool) String(pool); | |
| if(size) | |
| cell->APPEND_TAINTED( | |
| (const char *)ptr, size, | |
| statement_cstr, table->size()-1); | |
| (*row)+=cell; | |
| return false; | |
| } catch(...) { | |
| error=SQL_Error("exception occured in Table_sql_event_handlers::add_row_cell"); | |
| return true; | |
| } | |
| } | } |
| private: | private: |
| Line 765 MTable::MTable(Pool& apool) : Methoded(a | Line 792 MTable::MTable(Pool& apool) : Methoded(a |
| // ^table::load[file] | // ^table::load[file] |
| // ^table::load[nameless;file] | // ^table::load[nameless;file] |
| add_native_method("load", Method::CT_DYNAMIC, _load, 1, 2); | add_native_method("load", Method::CT_DYNAMIC, _load, 1, 3); |
| // ^table.save[file] | // ^table.save[file] |
| // ^table.save[nameless;file] | // ^table.save[nameless;file] |