--- parser3/src/classes/table.C 2002/09/18 08:52:49 1.165 +++ parser3/src/classes/table.C 2002/12/09 11:07:40 1.169 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_TABLE_C="$Date: 2002/09/18 08:52:49 $"; +static const char* IDENT_TABLE_C="$Date: 2002/12/09 11:07:40 $"; #include "classes.h" #include "pa_common.h" @@ -125,12 +125,19 @@ static void _create(Request& r, const St static void _load(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - // filename is last parameter - Value& vfile_name=params->as_no_junction(params->size()-1, - "file name must not be code"); - + 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) + filename_param_index++; + int options_param_index=filename_param_index+1; + // loading text - char *data=file_read_text(pool, r.absolute(vfile_name.as_string())); + char *data=file_read_text(pool, + r.absolute(params->as_string(filename_param_index, "file name must be string")), + true, + options_param_indexsize()?params->as_no_junction(options_param_index, "additional params must be hash").get_hash(&method_name):0 + ); // parse columns Array *columns; @@ -139,7 +146,7 @@ static void _load(Request& r, const Stri const char *file=origin.file; uint line=origin.line; #endif - if(params->size()==2) { + if(nameless) { columns=0; // nameless } else { columns=new(pool) Array(pool); @@ -304,11 +311,14 @@ static void _menu(Request& r, const Stri #ifndef DOXYGEN struct Row_info { + Request *r; Table *table; + Value *key_code; int key_field; Array *value_fields; Hash *hash; bool distinct; + int row; }; #endif static void table_row_to_hash(Array::Item *value, void *info) { @@ -316,24 +326,32 @@ static void table_row_to_hash(Array::Ite Row_info& ri=*static_cast(info); Pool& pool=ri.table->pool(); - if(ri.key_fieldsize(); i++) { - int value_field=ri.value_fields->get_int(i); - if(value_fieldcolumns()->get_string(value_field), - new(pool) VString(*row.get_string(value_field))); - } + const String *key; + if(ri.key_code) { + ri.table->set_current(ri.row++); // change context row + StringOrValue sv_processed=ri.r->process(*ri.key_code); + key=&sv_processed.as_string(); + } else + key=ri.key_fieldput_dont_replace(key, &result)) // put. existed? - if(!ri.distinct) - throw Exception("parser.runtime", - &key, - "duplicate key"); + VHash& result=*new(pool) VHash(pool); + Hash& hash=*result.get_hash(0); + for(int i=0; isize(); i++) { + int value_field=ri.value_fields->get_int(i); + if(value_fieldcolumns()->get_string(value_field), + new(pool) VString(*row.get_string(value_field))); } + + if(ri.hash->put_dont_replace(*key, &result)) // put. existed? + if(!ri.distinct) + throw Exception("parser.runtime", + key, + "duplicate key"); } static void _hash(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); @@ -341,24 +359,22 @@ static void _hash(Request& r, const Stri Value& result=*new(pool) VHash(pool); if(const Array *columns=self_table.columns()) if(columns->size()>0) { - const String& key_field_name=params->as_no_junction(0, - "key field name must not be code").as_string(); - int key_field=self_table.column_name2index(key_field_name, true); - bool distinct=false; int param_index=params->size()-1; - if(Hash *options= - params->as_no_junction(param_index, "param must not be code").get_hash(0)) { - --param_index; - int valid_options=0; - if(Value *vdistinct=(Value *)options->get(*sql_distinct_name)) { - valid_options++; - distinct=r.process_to_value(*vdistinct).as_bool(); + if(param_index>0) { + if(Hash *options= + params->as_no_junction(param_index, "param must not be code").get_hash(0)) { + --param_index; + int valid_options=0; + if(Value *vdistinct=(Value *)options->get(*sql_distinct_name)) { + valid_options++; + distinct=r.process_to_value(*vdistinct).as_bool(); + } + if(valid_options!=options->size()) + throw Exception("parser.runtime", + &method_name, + "called with invalid option"); } - if(valid_options!=options->size()) - throw Exception("parser.runtime", - &method_name, - "called with invalid option"); } if(param_index==2) // bad options param type throw Exception("parser.runtime", @@ -386,9 +402,16 @@ static void _hash(Request& r, const Stri value_fields+=i; } - // integers: key_field & value_fields - Row_info row_info={&self_table, key_field, &value_fields, result.get_hash(0), distinct}; + Value& key_param=params->get(0); + Value *key_code=key_param.get_junction()?&key_param:0; + int key_field=key_code?-1 + :self_table.column_name2index(key_param.as_string(), true); + + Row_info row_info={&r, &self_table, key_code, key_field, &value_fields, result.get_hash(0), distinct}; + + int saved_current=self_table.current(); self_table.for_each(table_row_to_hash, &row_info); + self_table.set_current(saved_current); } r.write_no_lang(result); } @@ -578,7 +601,7 @@ static void _join(Request& r, const Stri } #ifndef DOXYGEN -class Table_sql_event_handlers : public SQL_Driver_query_event_handlers { +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) : @@ -749,7 +772,7 @@ MTable::MTable(Pool& apool) : Methoded(a // ^table::load[file] // ^table::load[nameless;file] - add_native_method("load", Method::CT_DYNAMIC, _load, 1, 2); + add_native_method("load", Method::CT_DYNAMIC, _load, 1, 3); // ^table.save[file] // ^table.save[nameless;file]