--- parser3/src/classes/table.C 2001/07/09 16:13:17 1.92 +++ parser3/src/classes/table.C 2001/08/03 11:54:19 1.99 @@ -5,7 +5,7 @@ Author: Alexander Petrosyan (http://design.ru/paf) */ -static const char *RCSId="$Id: table.C,v 1.92 2001/07/09 16:13:17 parser Exp $"; +static const char *RCSId="$Id: table.C,v 1.99 2001/08/03 11:54:19 parser Exp $"; #include "pa_config_includes.h" @@ -65,10 +65,10 @@ static void _set(Request& r, const Strin // parse cells Array rows(pool); data.split(rows, &pos_after, "\n", 1, String::UL_CLEAN); - int size=rows.quick_size(); - for(int i=0; i=1 && _day<=monthDays) { char *buf=(char *)malloc(2+1); - sprintf(buf, "%02d", _day); - cell=new(pool) String(pool, buf); - } else - cell=new(pool) String(pool); + cell->APPEND_CLEAN(buf, sprintf(buf, "%02d", _day), + method_name.origin().file, method_name.origin().line); + } row+=cell; } *result+=&row; @@ -200,10 +199,18 @@ static Table *fill_week_days(Request& r, for(int curWeekDay=0; curWeekDay<7; curWeekDay++, t+=SECS_PER_DAY) { tm *tmOut=localtime(&t); Array& row=*new(pool) Array(pool, 4); - {char *buf=(char *)malloc(4+1); sprintf(buf, "%04d", 1900+tmOut->tm_year); row+=new(pool) String(pool, buf);} - {char *buf=(char *)malloc(2+1); sprintf(buf, "%02d", 1+tmOut->tm_mon); row+=new(pool) String(pool, buf);} - {char *buf=(char *)malloc(2+1); sprintf(buf, "%02d", tmOut->tm_mday); row+=new(pool) String(pool, buf);} - {char *buf=(char *)malloc(2+1); sprintf(buf, "%02d", tmOut->tm_wday); row+=new(pool) String(pool, buf);} +#define WDFILL(size, value) { \ + char *buf=(char *)malloc(size+1); \ + String *cell=new(pool) String(pool); \ + cell->APPEND_CLEAN(buf, sprintf(buf, "%0"#size"d", value), \ + method_name.origin().file, \ + method_name.origin().line); \ + row+=cell; \ + } + WDFILL(4, 1900+tmOut->tm_year); + WDFILL(2, 1+tmOut->tm_mon); + WDFILL(2, tmOut->tm_mday); + WDFILL(2, tmOut->tm_wday); *result+=&row; } @@ -248,15 +255,15 @@ static void _save(Request& r, const Stri if(params->size()==1) { // not nameless=named output // write out names line if(table.columns()) { // named table - for(int column=0; columnsize(); column++) { - if(column) - sdata.APPEND_CONST("\t"); - sdata.append(*static_cast(table.columns()->quick_get(column)), + Array_iter i(*table.columns()); + while(i.has_next()) { + sdata.append(*i.next_string(), //*static_cast(table.columns()->quick_get(column)), String::UL_TABLE); + if(i.has_next()) + sdata.APPEND_CONST("\t"); } } else { // nameless table - int lsize=table.size()?static_cast(table.get(0))->size():0; - if(lsize) + if(int lsize=table.size()?static_cast(table.get(0))->size():0) for(int column=0; column(table.quick_get(index)); - for(int column=0; columnsize(); column++) { - if(column) - sdata.APPEND_CONST("\t"); - sdata.append(*static_cast(row->quick_get(column)), + Array_iter i(table); + while(i.has_next()) { + Array_iter c(*static_cast(i.next())); + while(c.has_next()) { + sdata.append(*c.next_string(), //*static_cast(row->quick_get(column)), String::UL_TABLE); + if(c.has_next()) + sdata.APPEND_CONST("\t"); } sdata.APPEND_CONST("\n"); } @@ -284,15 +292,17 @@ static void _save(Request& r, const Stri sdata.cstr(), sdata.size(), true); } -static void _count(Request& r, const String&, MethodParams *) { +static void _count(Request& r, const String& method_name, MethodParams *) { Pool& pool=r.pool(); Value& value=*new(pool) VInt(pool, static_cast(r.self)->table().size()); + value.set_name(method_name); r.write_no_lang(value); } static void _line(Request& r, const String& method_name, MethodParams *) { Pool& pool=r.pool(); Value& value=*new(pool) VInt(pool, 1+static_cast(r.self)->table().current()); + value.set_name(method_name); r.write_no_lang(value); } @@ -304,6 +314,7 @@ static void _offset(Request& r, const St table.shift(r.process(offset_expr).as_int()); } else { Value& value=*new(pool) VInt(pool, table.current()); + value.set_name(method_name); r.write_no_lang(value); } } @@ -316,8 +327,9 @@ static void _menu(Request& r, const Stri VTable& vtable=*static_cast(r.self); Table& table=vtable.table(); bool need_delim=false; - vtable.lock(); int saved_current=table.current(); - for(int row=0; row(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; @@ -394,10 +378,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(); @@ -420,12 +405,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 @@ -524,7 +508,7 @@ static void _flip(Request& r, const Stri new_table+=&new_row; } - vtable.set_table(new_table); + r.write_no_lang(*new(pool) VTable(pool, &new_table)); } static void _append(Request& r, const String& method_name, MethodParams *params) { @@ -538,10 +522,7 @@ static void _append(Request& r, const St string.split(row, 0, "\t", 1, String::UL_CLEAN); VTable& vtable=*static_cast(r.self); - // disable ^a.menu{^a.append[]} - vtable.lock(); vtable.table()+=&row; - vtable.unlock(); } static void _join(Request& r, const String& method_name, MethodParams *params) { @@ -576,6 +557,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(); @@ -602,14 +631,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; @@ -619,35 +647,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) { @@ -734,10 +740,10 @@ static void _columns(Request& r, const S Table& source_table=static_cast(r.self)->table(); if(const Array *source_columns=source_table.columns()) { - int size=source_columns->quick_size(); - for(int i=0; iquick_get(i); + result_row+=i.next(); result_table+=&result_row; } } @@ -785,9 +791,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);