--- parser3/src/classes/table.C 2007/05/03 10:42:04 1.227 +++ parser3/src/classes/table.C 2007/11/14 09:45:21 1.237 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_TABLE_C="$Date: 2007/05/03 10:42:04 $"; +static const char * const IDENT_TABLE_C="$Date: 2007/11/14 09:45:21 $"; #include using namespace std; @@ -41,15 +41,8 @@ DECLARE_CLASS_VAR(table, new MTable, 0); extern String cycle_data_name; -// defines for globals - -#define SQL_BIND_NAME "bind" -#define SQL_DEFAULT_NAME "default" -#define SQL_DISTINCT_NAME "distinct" -#define SQL_VALUE_TYPE_NAME "type" #define TABLE_REVERSE_NAME "reverse" - // globals String sql_bind_name(SQL_BIND_NAME); @@ -130,6 +123,38 @@ static void check_option_param(bool opti "%s", msg); } +struct TableSeparators { + char column; const String* scolumn; + char encloser; const String* sencloser; + + TableSeparators(): + column('\t'), scolumn(new String("\t", false)), + encloser(0), sencloser(0) + {} + int load( HashStringValue& options ) { + int result=0; + if(Value* vseparator=options.get(PA_COLUMN_SEPARATOR_NAME)) { + scolumn=&vseparator->as_string(); + if(scolumn->length()!=1) + throw Exception(PARSER_RUNTIME, + scolumn, + "separator must be one character long"); + column=scolumn->first_char(); + result++; + } + if(Value* vencloser=options.get(PA_COLUMN_ENCLOSER_NAME)) { + sencloser=&vencloser->as_string(); + if(sencloser->length()!=1) + throw Exception(PARSER_RUNTIME, + sencloser, + "encloser must be one character long"); + encloser=sencloser->first_char(); + result++; + } + return result; + } +}; + static void _create(Request& r, MethodParams& params) { // clone/copy part? if(Table *source=params[0].get_table()) { @@ -140,20 +165,49 @@ static void _create(Request& r, MethodPa return; } - // data is last parameter + size_t data_param_index=0; + bool nameless=false; + + if(params.count()>1) { + if(params[0].is_string()){ // can be nameless only + const String& snameless=params.as_string(0, "called with more then 1 param, first param may be only string 'nameless' or junction"); + if(snameless!="nameless") + throw Exception(PARSER_RUNTIME, + &snameless, + "table::create called with more then 1 param, first param may be only 'nameless'"); + nameless=true; + data_param_index++; + } + } + + HashStringValue *options=0; + TableSeparators separators; + + size_t options_param_index=data_param_index+1; + if( + options_param_indexsplit(*columns, col_pos_after, "\t", String::L_AS_IS); + head[0]->split(*columns, col_pos_after, *separators.scolumn, String::L_AS_IS); } } @@ -180,7 +234,7 @@ static void _create(Request& r, MethodPa continue; size_t col_pos_after=0; - string.split(*row, col_pos_after, "\t", String::L_AS_IS); + string.split(*row, col_pos_after, *separators.scolumn, String::L_AS_IS); table+=row; } @@ -270,40 +324,8 @@ static void skip_empty_and_comment_lines } } -struct TableSeparators { - char column; const String* scolumn; - char encloser; const String* sencloser; - - TableSeparators(): - column('\t'), scolumn(new String("\t", false)), - encloser(0), sencloser(0) - {} - int load( HashStringValue& options ) { - int result=0; - if(Value* vseparator=options.get(PA_COLUMN_SEPARATOR_NAME)) { - scolumn=&vseparator->as_string(); - if(scolumn->length()!=1) - throw Exception(PARSER_RUNTIME, - scolumn, - "separator must be one character long"); - column=scolumn->first_char(); - result++; - } - if(Value* vencloser=options.get(PA_COLUMN_ENCLOSER_NAME)) { - sencloser=&vencloser->as_string(); - if(sencloser->length()!=1) - throw Exception(PARSER_RUNTIME, - sencloser, - "encloser must be one character long"); - encloser=sencloser->first_char(); - result++; - } - return result; - } -}; - static void _load(Request& r, MethodParams& params) { - const String& first_param=params.as_string(0, "file name must be string"); + const String& first_param=params.as_string(0, FILE_NAME_MUST_BE_STRING); int filename_param_index=0; bool nameless=first_param=="nameless"; if(nameless) @@ -321,7 +343,7 @@ static void _load(Request& r, MethodPara // loading text char *data=file_read_text(r.charsets, - r.absolute(params.as_string(filename_param_index, "file name must be string")), + r.absolute(params.as_string(filename_param_index, FILE_NAME_MUST_BE_STRING)), true, options ); @@ -405,9 +427,9 @@ void maybe_enclose( ostringstream& to, c to<0) { if(HashStringValue* options= - params.as_no_junction(param_index, "param must not be code").get_hash() + params.as_no_junction(param_index, PARAM_MUST_NOT_BE_CODE).get_hash() ){ --param_index; int valid_options=0; @@ -750,27 +793,13 @@ static void _hash(Request& r, MethodPara 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 + if(value_type==C_TABLE){ // $.distinct[tables] was specified already throw Exception(PARSER_RUNTIME, 0, - "you can't specify $.distinct[tables] and $.values[] together."); + "you can't specify $.distinct[tables] and $.type[] together."); } else { valid_options++; - Value& vvalue_type_value=r.process_to_value(*vvalue_type_code); - if(vvalue_type_value.is_string()) { - const String& svalue_type=*vvalue_type_value.get_string(); - if(svalue_type == "table"){ - value_type=C_TABLE; - } else if (svalue_type == "string") { - value_type=C_STRING; - } else if (svalue_type == "hash") { - value_type=C_HASH; - } else { - throw Exception(PARSER_RUNTIME, - &svalue_type, - "must be 'hash', 'table' or 'string'"); - } - } + value_type=get_value_type(r.process_to_value(*vvalue_type_code)); } } @@ -812,7 +841,7 @@ static void _hash(Request& r, MethodPara if(value_type==C_STRING) throw Exception(PARSER_RUNTIME, 0, - "with $.values[string] you must specify one value field(s)"); + "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; @@ -940,7 +969,7 @@ static bool _locate_name_value(Table& ta check_option_param(o.defined, params, 2, "locate by locate by name has parameters: name, value and, maybe, options"); const String& name=params.as_string(0, "column name must be string"); - const String& value=params.as_string(1, "value must be string"); + const String& value=params.as_string(1, VALUE_MUST_BE_STRING); return table.locate(name, value, o); } static void _locate(Request& r, MethodParams& params) { @@ -1194,10 +1223,15 @@ static void _sql(Request& r, MethodParam GET_SELF(r, VTable).set_table(result); } -static void _columns(Request& r, MethodParams&) { +static void _columns(Request& r, MethodParams& params) { + const String* column_column_name; + if(params.count()>0) + column_column_name=¶ms.as_string(0, COLUMN_NAME_MUST_BE_STRING); + else + column_column_name=new String("column"); Table::columns_type result_columns(new ArrayString); - *result_columns+=new String("column"); + *result_columns+=column_column_name; Table& result_table=*new Table(result_columns); Table& source_table=GET_SELF(r, VTable).table(); @@ -1213,7 +1247,7 @@ static void _columns(Request& r, MethodP } static void _select(Request& r, MethodParams& params) { - Value& vcondition=params.as_junction(0, "condition must be expression"); + Value& vcondition=params.as_expression(0, "condition must be number, bool or expression"); Table& source_table=GET_SELF(r, VTable).table(); Table& result_table=*new Table(source_table.columns()); @@ -1240,9 +1274,9 @@ MTable::MTable(): Methoded("table") { // ^table::create{data} // ^table::create[nameless]{data} // ^table::create[table] - add_native_method("create", Method::CT_DYNAMIC, _create, 1, 2); + add_native_method("create", Method::CT_DYNAMIC, _create, 1, 3); // old name for compatibility with <= v 1.141 2002/01/25 11:33:45 paf - add_native_method("set", Method::CT_DYNAMIC, _create, 1, 2); + add_native_method("set", Method::CT_DYNAMIC, _create, 1, 3); // ^table::load[file] // ^table::load[nameless;file] @@ -1294,8 +1328,8 @@ MTable::MTable(): Methoded("table") { // ^table:sql[query][$.limit(1) $.offset(2)] add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2); - // ^table:columns[] - add_native_method("columns", Method::CT_DYNAMIC, _columns, 0, 0); + // ^table:columns[[column name]] + add_native_method("columns", Method::CT_DYNAMIC, _columns, 0, 1); // ^table.select(expression) = table add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);