--- parser3/src/classes/hash.C 2003/02/04 14:04:45 1.54.2.3 +++ parser3/src/classes/hash.C 2003/04/04 10:38:26 1.55 @@ -1,11 +1,11 @@ /** @file Parser: @b hash parser class. - Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_HASH_C="$Date: 2003/02/04 14:04:45 $"; +static const char* IDENT_HASH_C="$Date: 2003/04/04 10:38:26 $"; #include "classes.h" #include "pa_request.h" @@ -20,7 +20,7 @@ static const char* IDENT_HASH_C="$Date: class MHash : public Methoded { public: // VStateless_class - ValuePtr create_new_value() { return ValuePtr(new VHash()); } + Value *create_new_value(Pool& pool) { return new(pool) VHash(pool); } public: MHash(Pool& pool); @@ -34,7 +34,7 @@ public: // Methoded class Hash_sql_event_handlers: public SQL_Driver_query_event_handlers { public: Hash_sql_event_handlers(Pool& apool, const String& amethod_name, - const String& astatement_string, const char* astatement_cstr, + const String& astatement_string, const char *astatement_cstr, bool adistinct, Hash& arows_hash): pool(apool), @@ -50,7 +50,7 @@ public: try { String *column=new(pool) String(pool); column->APPEND_TAINTED( - (const char* )ptr, size, + (const char *)ptr, size, statement_cstr, 0); columns+=column; @@ -79,7 +79,7 @@ public: String *cell=new(pool) String(pool); if(size) cell->APPEND_TAINTED( - (const char* )ptr, size, + (const char *)ptr, size, statement_cstr, row_index++); if(column_index==0) { VHash *row_vhash=new(pool) VHash(pool); @@ -105,7 +105,7 @@ public: private: Pool& pool; const String& method_name; - const String& statement_string; const char* statement_cstr; + const String& statement_string; const char *statement_cstr; bool distinct; Hash& rows_hash; Hash *row_hash; @@ -119,24 +119,45 @@ static void copy_all_overwrite_to(const Hash& dest=*static_cast(info); dest.put(key, value); } -static void _create_or_add(Request& r, StringPtr method_name, MethodParams& params) { +static void _create_or_add(Request& r, const String& method_name, MethodParams *params, + bool is_create) { Pool& pool=r.pool(); - if(params.count()) { - Value& vb=params.as_no_junction(0, "param must be hash"); - if(Hash *b=vb.get_hash(&method_name)) - b->for_each(copy_all_overwrite_to, &static_cast(r.get_self())->hash(&method_name)); + if(params->size()) { + Value& vb_maybehash=params->as_no_junction(0, "param must be hash"); + if(VHash* vbh=static_cast(vb_maybehash.as("hash", false))) { + VHash& vah=*static_cast(r.get_self()); + + Hash& a=vah.hash(&method_name); + Hash& b=vbh->hash(&method_name); + b.for_each(copy_all_overwrite_to, &a); + + if(is_create) + vah.set_default(vbh->get_default()); + } else + throw Exception("parser.runtime", + &method_name, + "param must be hash"); + + } } +static void _create(Request& r, const String& method_name, MethodParams *params) { + _create_or_add(r, method_name, params, true); +} +static void _add(Request& r, const String& method_name, MethodParams *params) { + _create_or_add(r, method_name, params, false); +} + static void remove_key_from(const Hash::Key& key, Hash::Val *value, void *info) { Hash& dest=*static_cast(info); dest.remove(key); } -static void _sub(Request& r, StringPtr method_name, MethodParams& params) { +static void _sub(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - Value& vb=params.as_no_junction(0, "param must be hash"); + Value& vb=params->as_no_junction(0, "param must be hash"); if(Hash *b=vb.get_hash(&method_name)) b->for_each(remove_key_from, &static_cast(r.get_self())->hash(&method_name)); } @@ -145,13 +166,13 @@ static void copy_all_dontoverwrite_to(co Hash& dest=*static_cast(info); dest.put_dont_replace(key, value); } -static void _union(Request& r, StringPtr method_name, MethodParams& params) { +static void _union(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); // dest = copy of self Hash& dest=*new(pool) Hash(static_cast(r.get_self())->hash(&method_name)); // dest += b - Value& vb=params.as_no_junction(0, "param must be hash"); + Value& vb=params->as_no_junction(0, "param must be hash"); if(Hash *b=vb.get_hash(&method_name)) b->for_each(copy_all_dontoverwrite_to, &dest); @@ -173,13 +194,13 @@ static void copy_intersection_to(const H if(i.b->get(key)) i.dest->put_dont_replace(key, value); } -static void _intersection(Request& r, StringPtr method_name, MethodParams& params) { +static void _intersection(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); // dest = copy of self Hash& dest=*new(pool) Hash(pool); // dest += b - Value& vb=params.as_no_junction(0, "param must be hash"); + Value& vb=params->as_no_junction(0, "param must be hash"); if(Hash *b=vb.get_hash(&method_name)) { Copy_intersection_to_info info={ b, @@ -196,7 +217,7 @@ static void *intersects(const Hash::Key& return static_cast(info)->get(key); } -static void _intersects(Request& r, StringPtr method_name, MethodParams& params) { +static void _intersects(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); bool yes=false; @@ -204,7 +225,7 @@ static void _intersects(Request& r, Stri // dest = copy of self Hash& dest=*new(pool) Hash(pool); // dest += b - Value& vb=params.as_no_junction(0, "param must be hash"); + Value& vb=params->as_no_junction(0, "param must be hash"); if(Hash *b=vb.get_hash(&method_name)) yes=static_cast(r.get_self())->hash(&method_name).first_that(intersects, b)!=0; @@ -213,16 +234,16 @@ static void _intersects(Request& r, Stri } -static void _sql(Request& r, StringPtr method_name, MethodParams& params) { +static void _sql(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - Value& statement=params.as_junction(0, "statement must be code"); + Value& statement=params->as_junction(0, "statement must be code"); ulong limit=0; ulong offset=0; bool distinct=false; - if(params.count()>1) { - Value& voptions=params.as_no_junction(1, "options must be hash, not code"); + if(params->size()>1) { + Value& voptions=params->as_no_junction(1, "options must be hash, not code"); if(!voptions.is_string()) if(Hash *options=voptions.get_hash(&method_name)) { int valid_options=0; @@ -250,7 +271,7 @@ static void _sql(Request& r, StringPtr m Temp_lang temp_lang(r, String::UL_SQL); const String& statement_string=r.process_to_string(statement); - const char* statement_cstr= + const char *statement_cstr= statement_string.cstr(String::UL_UNSPECIFIED, r.connection(&method_name)); Hash& hash=static_cast(r.get_self())->hash(&method_name); hash.clear(); @@ -273,7 +294,7 @@ static void keys_collector(const Hash::K row+=&key; table+=&row; } -static void _keys(Request& r, StringPtr method_name, MethodParams& ) { +static void _keys(Request& r, const String& method_name, MethodParams *) { Pool& pool=r.pool(); Array& columns=*new(pool) Array(pool); @@ -285,17 +306,17 @@ static void _keys(Request& r, StringPtr r.write_no_lang(*new(pool) VTable(pool, &table)); } -static void _count(Request& r, StringPtr method_name, MethodParams& ) { +static void _count(Request& r, const String& method_name, MethodParams *) { Pool& pool=r.pool(); r.write_no_lang( *new(pool) VInt(pool, static_cast(r.get_self())->hash(&method_name).size())); } -static void _delete(Request& r, StringPtr method_name, MethodParams& params) { +static void _delete(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - static_cast(r.get_self())->hash(&method_name).remove(params.as_string(0, "key must be string")); + static_cast(r.get_self())->hash(&method_name).remove(params->as_string(0, "key must be string")); } #ifndef DOXYGEN @@ -329,12 +350,12 @@ static void one_foreach_cycle(const Hash } i.r->write_pass_lang(sv_processed); } -static void _foreach(Request& r, StringPtr method_name, MethodParams& params) { +static void _foreach(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); - const String& key_var_name=params.as_string(0, "key-var name must be string"); - const String& value_var_name=params.as_string(1, "value-var name must be string"); - Value& body_code=params.as_junction(2, "body must be code"); - Value *delim_maybe_code=params.count()>3?¶ms.get(3):0; + const String& key_var_name=params->as_string(0, "key-var name must be string"); + const String& value_var_name=params->as_string(1, "value-var name must be string"); + Value& body_code=params->as_junction(2, "body must be code"); + Value *delim_maybe_code=params->size()>3?¶ms->get(3):0; Foreach_info info={ &r, @@ -356,9 +377,9 @@ static void _foreach(Request& r, StringP MHash::MHash(Pool& apool) : Methoded(apool, "hash") { // ^hash::create[[copy_from]] - add_native_method("create", Method::CT_DYNAMIC, _create_or_add, 0, 1); + add_native_method("create", Method::CT_DYNAMIC, _create, 0, 1); // ^hash.add[add_from] - add_native_method("add", Method::CT_DYNAMIC, _create_or_add, 1, 1); + add_native_method("add", Method::CT_DYNAMIC, _add, 1, 1); // ^hash.sub[sub_from] add_native_method("sub", Method::CT_DYNAMIC, _sub, 1, 1); // ^a.union[b] = hash