--- parser3/src/classes/hash.C 2003/01/31 12:34:26 1.54.2.2 +++ parser3/src/classes/hash.C 2003/04/25 11:39:54 1.56 @@ -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/01/31 12:34:26 $"; +static const char* IDENT_HASH_C="$Date: 2003/04/25 11:39:54 $"; #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,15 +119,34 @@ static void copy_all_overwrite_to(const Hash& dest=*static_cast(info); dest.put(key, value); } -static void _create_or_add(Request& r, const String& 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->size()) { - 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)); + 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 if(!vb_maybehash.is_string()) // allow ^hash::create[^rem{xxx}] + 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); @@ -250,7 +269,7 @@ static void _sql(Request& r, const Strin 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(); @@ -356,9 +375,9 @@ static void _foreach(Request& r, const S 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