--- parser3/src/classes/table.C 2001/07/18 10:06:04 1.93 +++ parser3/src/classes/table.C 2001/07/28 12:07:26 1.97 @@ -5,7 +5,7 @@ Author: Alexander Petrosyan (http://design.ru/paf) */ -static const char *RCSId="$Id: table.C,v 1.93 2001/07/18 10:06:04 parser Exp $"; +static const char *RCSId="$Id: table.C,v 1.97 2001/07/28 12:07:26 parser Exp $"; #include "pa_config_includes.h" @@ -349,34 +349,6 @@ static void _empty(Request& r, const Str r.write_no_lang(*new(pool) VBool(pool, table.size()==0)); } -/// used by table: _record / store_column_item_to_hash -struct Record_info { - Pool *pool; - Table *table; - Hash *hash; -}; -static void store_column_item_to_hash(Array::Item *item, void *info) { - Record_info& ri=*static_cast(info); - String& column_name=*static_cast(item); - Value *value; - if(const String *column_item=ri.table->item(column_name)) - value=new(*ri.pool) VString(*column_item); - else - value=new(*ri.pool) VVoid(*ri.pool); - ri.hash->put(column_name, value); -} -static void _record(Request& r, const String& method_name, MethodParams *) { - Table& table=static_cast(r.self)->table(); - if(const Array *columns=table.columns()) { - Pool& pool=r.pool(); - Value& result=*new(pool) VHash(pool); - Record_info record_info={&pool, &table, result.get_hash()}; - columns->for_each(store_column_item_to_hash, &record_info); - result.set_name(method_name); - r.write_no_lang(result); - } -} - /// used by table: _hash / table_row_to_hash struct Row_info { Table *table; @@ -404,10 +376,11 @@ static void table_row_to_hash(Array::Ite } } static void _hash(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); Table& table=static_cast(r.self)->table(); + Value& result=*new(pool) VHash(pool); if(const Array *columns=table.columns()) if(columns->size()>1) { - Pool& pool=r.pool(); const String& key_field_name=params->as_no_junction(0, "key field name must not be code").as_string(); @@ -430,12 +403,11 @@ static void _hash(Request& r, const Stri } // integers: key_field & value_fields - Value& result=*new(pool) VHash(pool); Row_info row_info={&table, key_field, &value_fields, result.get_hash()}; table.for_each(table_row_to_hash, &row_info); - result.set_name(method_name); - r.write_no_lang(result); } + result.set_name(method_name); + r.write_no_lang(result); } /// used by table: _sort / sort_cmp_string|sort_cmp_double @@ -586,6 +558,54 @@ static void _join(Request& r, const Stri } } +#ifndef DOXYGEN +class Table_sql_event_handlers : public SQL_Driver_query_event_handlers { +public: + Table_sql_event_handlers(Pool& apool, const String& amethod_name, + const String& astatement_string, const char *astatement_cstr) : + pool(apool), + method_name(amethod_name), + statement_string(astatement_string), + statement_cstr(astatement_cstr), + columns(*new(pool) Array(pool)), + row(0), row_index(0), + table(0) + { + } + + void add_column(void *ptr, size_t size) { + String *column=new(pool) String(pool); + column->APPEND_TAINTED( + (const char *)ptr, size, + 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, + statement_cstr, row_index++); + (*row)+=cell; + } + +private: + Pool& pool; + const String& method_name; + const String& statement_string; const char *statement_cstr; + Array& columns; + Array *row; + uint row_index; +public: + Table *table; +}; +#endif static void _sql(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); @@ -612,14 +632,13 @@ static void _sql(Request& r, const Strin const String& statement_string=r.process(statement).as_string(); const char *statement_cstr= statement_string.cstr(String::UL_UNSPECIFIED, r.connection); - unsigned int sql_column_count; SQL_Driver::Cell *sql_columns; - unsigned long sql_row_count; SQL_Driver::Cell **sql_rows; + Table_sql_event_handlers handlers(pool, method_name, + statement_string, statement_cstr); bool need_rethrow=false; Exception rethrow_me; PTRY { r.connection->query( statement_cstr, offset, limit, - &sql_column_count, &sql_columns, - &sql_row_count, &sql_rows); + handlers); } PCATCH(e) { // query problem rethrow_me=e; need_rethrow=true; @@ -629,35 +648,13 @@ static void _sql(Request& r, const Strin PTHROW(rethrow_me.type(), rethrow_me.code(), &statement_string, // setting more specific source [were url] rethrow_me.comment()); - - Array& table_columns=*new(pool) Array(pool); - for(unsigned int i=0; i(r.self)->set_table(table); + static_cast(r.self)->set_table(*result); } static void _dir(Request& r, const String& method_name, MethodParams *params) { @@ -795,9 +792,6 @@ MTable::MTable(Pool& apool) : Methoded(a // ^table.empty[] add_native_method("empty", Method::CT_DYNAMIC, _empty, 0, 0); - // ^table.record[] - add_native_method("record", Method::CT_DYNAMIC, _record, 0, 0); - // ^table:hash[key field name] // ^table:hash[key field name][value field name;...] add_native_method("hash", Method::CT_DYNAMIC, _hash, 1, 1000);