--- parser3/src/classes/table.C 2010/10/21 15:06:29 1.276 +++ parser3/src/classes/table.C 2011/05/15 13:20:07 1.280 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_TABLE_C="$Date: 2010/10/21 15:06:29 $"; +static const char * const IDENT_TABLE_C="$Date: 2011/05/15 13:20:07 $"; #if (!defined(NO_STRINGSTREAM) && !defined(FREEBSD4)) #include @@ -21,6 +21,7 @@ static const char * const IDENT_TABLE_C= #include "pa_vint.h" #include "pa_sql_connection.h" #include "pa_vbool.h" +#include "pa_array.h" // class @@ -588,8 +589,22 @@ static void _save(Request& r, MethodPara #endif // don't use stringstream } -static void _count(Request& r, MethodParams&) { - int result=GET_SELF(r, VTable).table().count(); +static void _count(Request& r, MethodParams& params) { + Table& table=GET_SELF(r, VTable).table(); + size_t result=0; + if(params.count()) { + const String& param=params.as_string(0, PARAMETER_MUST_BE_STRING); + if(param == "columns") + result = table.columns() ? table.columns()->count() : 0; + else if(param == "cells") + result = table.count() ? table[table.current()]->count() : 0; + else if(param == "rows") // synonim for ^table.count[] + result = table.count(); + else + throw Exception(PARSER_RUNTIME, ¶m, "parameter must be 'columns', 'cells' and 'rows' only"); + } else + result = table.count(); + r.write_no_lang(*new VInt(result)); } @@ -1063,7 +1078,7 @@ public: columns(*new ArrayString), row(0), table(0) { } - bool add_column(SQL_Error& error, const char *str, size_t length) { + bool add_column(SQL_Error& error, const char *str, size_t ) { try { columns+=new String(str, String::L_TAINTED /* no length as 0x00 can be inside */); return false; @@ -1091,7 +1106,7 @@ public: return true; } } - bool add_row_cell(SQL_Error& error, const char* str, size_t length) { + bool add_row_cell(SQL_Error& error, const char* str, size_t ) { try { *row+=new String(str, String::L_TAINTED /* no length as 0x00 can be inside */); return false; @@ -1242,16 +1257,59 @@ static void _select(Request& r, MethodPa Table& source_table=GET_SELF(r, VTable).table(); Table& result_table=*new Table(source_table.columns()); + int limit=source_table.count(); + int offset = 0; + bool reverse = false; + + if(params.count()>1) { + Value& voptions=params.as_no_junction(1, "options must be hash, not code"); + if(voptions.is_defined() && !voptions.is_string()) + if(HashStringValue* options=voptions.get_hash()) { + int valid_options=0; + if(Value* vlimit=options->get(sql_limit_name)) { + valid_options++; + limit=r.process_to_value(*vlimit).as_int(); + } + if(Value* voffset=options->get(sql_offset_name)) { + valid_options++; + offset=r.process_to_value(*voffset).as_int(); + } + if(Value* vreverse=options->get(table_reverse_name)) { + valid_options++; + reverse=r.process_to_value(*vreverse).as_bool(); + } + if(valid_options!=options->count()) + throw Exception(PARSER_RUNTIME, + 0, + "called with invalid option"); + } else + throw Exception(PARSER_RUNTIME, + 0, + "options must be hash"); + } + int saved_current=source_table.current(); int size=source_table.count(); - for(int row=0; row=0 && result_table.count() < limit; row--) { + source_table.set_current(row); + + bool condition=r.process_to_value(vcondition, false/*don't intercept string*/).as_bool(); - bool condition=r.process_to_value(vcondition, - false/*don't intercept string*/).as_bool(); + if(condition && ++appended > offset) // ...condition is true, adding to the result + result_table+=source_table[row]; + } + } else { + for(int row=0; row < size && result_table.count() < limit; row++) { + source_table.set_current(row); - if(condition) // ...condition is true= - result_table+=source_table[row]; // =green light to go to result + bool condition=r.process_to_value(vcondition, false/*don't intercept string*/).as_bool(); + + if(condition && ++appended > offset) // ...condition is true, adding to the result + result_table+=source_table[row]; + } } source_table.set_current(saved_current); @@ -1279,7 +1337,10 @@ MTable::MTable(): Methoded("table") { // add_native_method("save_old", Method::CT_DYNAMIC, _save_old, 1, 3); // ^table.count[] - add_native_method("count", Method::CT_DYNAMIC, _count, 0, 0); + // ^table.count[rows] + // ^table.count[columns] + // ^table.count[cells] + add_native_method("count", Method::CT_DYNAMIC, _count, 0, 1); // ^table.line[] add_native_method("line", Method::CT_DYNAMIC, _line, 0, 0); @@ -1322,5 +1383,5 @@ MTable::MTable(): Methoded("table") { add_native_method("columns", Method::CT_DYNAMIC, _columns, 0, 1); // ^table.select(expression) = table - add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1); + add_native_method("select", Method::CT_DYNAMIC, _select, 1, 2); }