--- parser3/src/classes/table.C 2007/10/16 09:30:10 1.236 +++ parser3/src/classes/table.C 2008/04/07 15:14:32 1.240 @@ -5,10 +5,12 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_TABLE_C="$Date: 2007/10/16 09:30:10 $"; +static const char * const IDENT_TABLE_C="$Date: 2008/04/07 15:14:32 $"; +#ifndef NO_STRINGSTREAM #include using namespace std; +#endif #include "classes.h" #include "pa_vmethod_frame.h" @@ -429,7 +431,7 @@ void maybe_enclose( ostringstream& to, c /* static void _save_old(Request& r, MethodParams& params) { - const String& first_arg=params.as_string(0, "first argument must not be code"); + const String& first_arg=params.as_string(0, FIRST_ARG_MUST_NOT_BE_CODE); size_t param_index=1; bool do_append=false; @@ -515,7 +517,7 @@ static void _save_old(Request& r, Method */ static void _save(Request& r, MethodParams& params) { - const String& first_arg=params.as_string(0, "first argument must not be code"); + const String& first_arg=params.as_string(0, FIRST_ARG_MUST_NOT_BE_CODE); size_t param_index=1; bool do_append=false; @@ -555,6 +557,8 @@ static void _save(Request& r, MethodPara Table& table=GET_SELF(r, VTable).table(); +#ifndef NO_STRINGSTREAM + ostringstream ost(stringstream::out); // process header @@ -572,7 +576,7 @@ static void _save(Request& r, MethodPara if(separators.encloser) { ost< i(*table.columns()); i.has_next(); ) { + maybe_enclose( sdata, *i.next(), separators.encloser, separators.sencloser ); + if(i.has_next()) + sdata<<*separators.scolumn; + } + } else { // nameless table [we were asked to output column names] + if(int lsize=table.count()?table[0]->count():0) + for(int column=0; column i(table); + while(i.has_next()) { + for(Array_iterator c(*i.next()); c.has_next(); ) { + maybe_enclose( sdata, *c.next(), separators.encloser, separators.sencloser ); + if(c.has_next()) + sdata<<*separators.scolumn; + } + sdata.append_know_length("\n", 1, String::L_CLEAN); + } + + // write + { + const char* data_cstr=sdata.cstr(); + file_write(r.absolute(file_name), + data_cstr, sdata.length(), true, do_append); + if(*data_cstr) // not empty (when empty it's not heap memory) + pa_free((void*)data_cstr); // not needed anymore + } +#endif } static void _count(Request& r, MethodParams&) { @@ -766,18 +816,16 @@ Table2hash_value_type get_value_type(Val static void _hash(Request& r, MethodParams& params) { Table& self_table=GET_SELF(r, VTable).table(); VHash& result=*new VHash; - if(Table::columns_type columns=self_table.columns()) + if(Table::columns_type columns=self_table.columns()){ if(columns->count()>0) { Table2hash_distint distinct=D_ILLEGAL; Table2hash_value_type value_type=C_HASH; int param_index=params.count()-1; if(param_index>0) { - if(HashStringValue* options= - params.as_no_junction(param_index, "param must not be code").get_hash() - ){ + if(HashStringValue* options=params.as_no_junction(param_index, PARAM_MUST_NOT_BE_CODE).get_hash()){ // options where specified --param_index; int valid_options=0; - if(Value* vdistinct_code=options->get(sql_distinct_name)) { + if(Value* vdistinct_code=options->get(sql_distinct_name)) { // $.distinct ? valid_options++; Value& vdistinct_value=r.process_to_value(*vdistinct_code); if(vdistinct_value.is_string()) { @@ -785,23 +833,24 @@ static void _hash(Request& r, MethodPara if(sdistinct=="tables") { value_type=C_TABLE; distinct=D_FIRST; - } else + } else { throw Exception(PARSER_RUNTIME, &sdistinct, "must be 'tables' or true/false"); - } else + } + } else { distinct=vdistinct_value.as_bool()?D_FIRST:D_ILLEGAL; + } } - if(Value* vvalue_type_code=options->get(sql_value_type_name)) { - if(value_type==C_TABLE){ // $.distinct[tables] was specified already + if(Value* vvalue_type_code=options->get(sql_value_type_name)) { // $.type ? + if(value_type==C_TABLE) // $.distinct[tables] already was specified throw Exception(PARSER_RUNTIME, 0, - "you can't specify $.distinct[tables] and $.type[] together."); - } else { - valid_options++; - value_type=get_value_type(r.process_to_value(*vvalue_type_code)); - } - } + "you can't specify $.distinct[tables] and $.type[] together"); + + valid_options++; + value_type=get_value_type(r.process_to_value(*vvalue_type_code)); + } if(valid_options!=options->count()) throw Exception(PARSER_RUNTIME, @@ -809,48 +858,46 @@ static void _hash(Request& r, MethodPara "called with invalid option"); } } - if(param_index==2) // bad options param type + + if(param_index==2) // options was specified but not as hash throw Exception(PARSER_RUNTIME, 0, "options must be hash"); Array value_fields; - if(param_index>0) { + if(param_index==0){ // list of columns wasn't specified + if(value_type==C_STRING) // $.type[string] + throw Exception(PARSER_RUNTIME, + 0, + "you must specify one value field with option $.type[string]"); + + for(size_t i=0; icount(); i++) // by all columns, including key + value_fields+=i; + + } else { // list of columns was specified if(value_type==C_TABLE) throw Exception(PARSER_RUNTIME, 0, - "in distinct[tables] mode you may not specify value field(s)"); + "you can't specify value field(s) with option $.distinct[tables] or $.type[tables]"); + Value& value_fields_param=params.as_no_junction(param_index, "value field(s) must not be code"); - if(value_fields_param.is_string()) { - value_fields+=self_table.column_name2index( - *value_fields_param.get_string(), true); - } else if(Table* value_fields_table=value_fields_param.get_table()) { - for(Array_iterator i(*value_fields_table); - i.has_next(); ) { - const String& value_field_name - =*i.next()->get(0); - value_fields - +=self_table.column_name2index(value_field_name, true); + if(value_fields_param.is_string()) { // one column as string was specified + value_fields+=self_table.column_name2index(*value_fields_param.get_string(), true); + } else if(Table* value_fields_table=value_fields_param.get_table()) { // list of columns were specified in table + for(Array_iterator i(*value_fields_table); i.has_next(); ) { + const String& value_field_name =*i.next()->get(0); + value_fields +=self_table.column_name2index(value_field_name, true); } } else throw Exception(PARSER_RUNTIME, 0, "value field(s) must be string or table"); - - } else { // by all columns, including key - if(value_type==C_STRING) - throw Exception(PARSER_RUNTIME, - 0, - "with $.type[string] you must specify one value field(s)"); - // if(!(distinct!=D_ILLEGAL && distinct!=D_FIRST)) - for(size_t i=0; icount(); i++) - value_fields+=i; } if(value_type==C_STRING && value_fields.count()!=1) throw Exception(PARSER_RUNTIME, 0, - "you can specify one value field with this $.type[]."); + "you can specify only one value field with option $.type[string]"); { Value* key_param=¶ms[0]; @@ -875,6 +922,7 @@ static void _hash(Request& r, MethodPara result.extract_default(); } } + } r.write_no_lang(result); } @@ -1303,8 +1351,8 @@ MTable::MTable(): Methoded("table") { // ^table.menu{code}[delim] add_native_method("menu", Method::CT_DYNAMIC, _menu, 1, 2); - // ^table:hash[key field name] - // ^table:hash[key field name][value field name(s) string/table] + // ^table.hash[key field name] + // ^table.hash[key field name][value field name(s) string/table] add_native_method("hash", Method::CT_DYNAMIC, _hash, 1, 3); // ^table.sort{string-key-maker} ^table.sort{string-key-maker}[desc|asc] @@ -1324,11 +1372,11 @@ MTable::MTable(): Methoded("table") { add_native_method("join", Method::CT_DYNAMIC, _join, 1, 2); - // ^table:sql[query] - // ^table:sql[query][$.limit(1) $.offset(2)] + // ^table::sql[query] + // ^table::sql[query][$.limit(1) $.offset(2)] add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2); - // ^table:columns[[column name]] + // ^table.columns[[column name]] add_native_method("columns", Method::CT_DYNAMIC, _columns, 0, 1); // ^table.select(expression) = table