|
|
| version 1.54.2.13.2.12, 2003/03/27 14:51:27 | version 1.66, 2004/02/17 11:08:38 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: @b hash parser class. | Parser: @b hash parser class. |
| Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| static const char* IDENT_HASH_C="$Date$"; | static const char * const IDENT_HASH_C="$Date$"; |
| #include "classes.h" | #include "classes.h" |
| #include "pa_vmethod_frame.h" | #include "pa_vmethod_frame.h" |
| Line 22 static const char* IDENT_HASH_C="$Date$" | Line 22 static const char* IDENT_HASH_C="$Date$" |
| class MHash: public Methoded { | class MHash: public Methoded { |
| public: // VStateless_class | public: // VStateless_class |
| Value* create_new_value() { return new VHash(); } | Value* create_new_value(Pool&) { return new VHash(); } |
| public: | public: |
| MHash(); | MHash(); |
| Line 55 public: | Line 55 public: |
| row_hash(0), | row_hash(0), |
| column_index(0) { | column_index(0) { |
| } | } |
| bool add_column(SQL_Error& error, const char* str, size_t size) { | bool add_column(SQL_Error& error, const char* str, size_t length) { |
| try { | try { |
| columns+=new String(str, size, true); | columns+=new String(str, length, true); |
| return false; | return false; |
| } catch(...) { | } catch(...) { |
| error=SQL_Error("exception occured in Hash_sql_event_handlers::add_column"); | error=SQL_Error("exception occured in Hash_sql_event_handlers::add_column"); |
| Line 78 public: | Line 78 public: |
| column_index=0; | column_index=0; |
| return false; | return false; |
| } | } |
| bool add_row_cell(SQL_Error& error, const char *ptr, size_t size) { | bool add_row_cell(SQL_Error& error, const char *ptr, size_t length) { |
| try { | try { |
| String& cell=*new String; | String& cell=*new String; |
| if(size) | if(length) |
| cell.append_help_length(ptr, size, String::L_TAINTED); | cell.append_know_length(ptr, length, String::L_TAINTED); |
| if(column_index==0) { | if(column_index==0) { |
| VHash* row_vhash=new VHash; | VHash* row_vhash=new VHash; |
| row_hash=&row_vhash->hash(); | row_hash=&row_vhash->hash(); |
| Line 113 static void copy_all_overwrite_to( | Line 113 static void copy_all_overwrite_to( |
| HashStringValue* dest) { | HashStringValue* dest) { |
| dest->put(key, value); | dest->put(key, value); |
| } | } |
| static void _create_or_add(Request& r, MethodParams* params) { | static void _create_or_add(Request& r, MethodParams& params) { |
| if(params->count()) { | if(params.count()) { |
| Value& vb=params->as_no_junction(0, "param must be hash"); | Value& vsrc=params.as_no_junction(0, "param must be hash"); |
| if(HashStringValue* b=vb.get_hash()) | if(HashStringValue* src=vsrc.get_hash()) { |
| b->for_each(copy_all_overwrite_to, &(GET_SELF(r, VHash).hash())); | HashStringValue* self=&(GET_SELF(r, VHash).hash()); |
| if(src==self) // same: doing nothing | |
| return; | |
| src->for_each(copy_all_overwrite_to, self); | |
| } | |
| } | } |
| } | } |
| Line 127 static void remove_key_from( | Line 131 static void remove_key_from( |
| HashStringValue* dest) { | HashStringValue* dest) { |
| dest->remove(key); | dest->remove(key); |
| } | } |
| static void _sub(Request& r, MethodParams* params) { | static void _sub(Request& r, MethodParams& params) { |
| Value& vb=params->as_no_junction(0, "param must be hash"); | Value& vsrc=params.as_no_junction(0, "param must be hash"); |
| if(HashStringValue* b=vb.get_hash()) | if(HashStringValue* src=vsrc.get_hash()) { |
| b->for_each(remove_key_from, &GET_SELF(r, VHash).hash()); | HashStringValue* self=&(GET_SELF(r, VHash).hash()); |
| if(src==self) { // same: clearing | |
| self->clear(); | |
| return; | |
| } | |
| src->for_each(remove_key_from, self); | |
| } | |
| } | } |
| static void copy_all_dontoverwrite_to( | static void copy_all_dontoverwrite_to( |
| Line 139 static void copy_all_dontoverwrite_to( | Line 149 static void copy_all_dontoverwrite_to( |
| HashStringValue* dest) { | HashStringValue* dest) { |
| dest->put_dont_replace(key, value); | dest->put_dont_replace(key, value); |
| } | } |
| static void _union(Request& r, MethodParams* params) { | static void _union(Request& r, MethodParams& params) { |
| // dest = copy of self | // dest = copy of self |
| Value& result=*new VHash(GET_SELF(r, VHash).hash()); | Value& result=*new VHash(GET_SELF(r, VHash).hash()); |
| // dest += b | // dest += b |
| Value& vb=params->as_no_junction(0, "param must be hash"); | Value& vsrc=params.as_no_junction(0, "param must be hash"); |
| if(HashStringValue* b=vb.get_hash()) | if(HashStringValue* src=vsrc.get_hash()) |
| b->for_each(copy_all_dontoverwrite_to, result.get_hash()); | src->for_each(copy_all_dontoverwrite_to, result.get_hash()); |
| // return result | // return result |
| r.write_no_lang(result); | r.write_no_lang(result); |
| Line 164 static void copy_intersection_to( | Line 174 static void copy_intersection_to( |
| if(info->b->get(key)) | if(info->b->get(key)) |
| info->dest->put_dont_replace(key, value); | info->dest->put_dont_replace(key, value); |
| } | } |
| static void _intersection(Request& r, MethodParams* params) { | static void _intersection(Request& r, MethodParams& params) { |
| Value& result=*new VHash; | Value& result=*new VHash; |
| // dest += b | // 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(HashStringValue* b=vb.get_hash()) { | if(HashStringValue* b=vb.get_hash()) { |
| Copy_intersection_to_info info={b, result.get_hash()}; | Copy_intersection_to_info info={b, result.get_hash()}; |
| GET_SELF(r, VHash).hash().for_each(copy_intersection_to, &info); | GET_SELF(r, VHash).hash().for_each(copy_intersection_to, &info); |
| Line 184 static bool intersects( | Line 194 static bool intersects( |
| return b->get(key)!=0; | return b->get(key)!=0; |
| } | } |
| static void _intersects(Request& r, MethodParams* params) { | static void _intersects(Request& r, MethodParams& params) { |
| bool result=false; | bool result=false; |
| Value& vb=params->as_no_junction(0, "param must be hash"); | Value& vb=params.as_no_junction(0, "param must be hash"); |
| if(HashStringValue* b=vb.get_hash()) | if(HashStringValue* b=vb.get_hash()) |
| result=GET_SELF(r, VHash).hash().first_that(intersects, b)!=0; | result=GET_SELF(r, VHash).hash().first_that(intersects, b)!=0; |
| Line 200 extern String sql_limit_name; | Line 210 extern String sql_limit_name; |
| extern String sql_offset_name; | extern String sql_offset_name; |
| extern String sql_default_name; | extern String sql_default_name; |
| extern String sql_distinct_name; | extern String sql_distinct_name; |
| static void _sql(Request& r, MethodParams* params) { | static void _sql(Request& r, MethodParams& params) { |
| Value& statement=params->as_junction(0, "statement must be code"); | Value& statement=params.as_junction(0, "statement must be code"); |
| ulong limit=0; | ulong limit=0; |
| ulong offset=0; | ulong offset=0; |
| bool distinct=false; | bool distinct=false; |
| if(params->count()>1) { | if(params.count()>1) { |
| Value& voptions=params->as_no_junction(1, "options must be hash, not code"); | Value& voptions=params.as_no_junction(1, "options must be hash, not code"); |
| if(!voptions.is_string()) | if(!voptions.is_string()) |
| if(HashStringValue* options=voptions.get_hash()) { | if(HashStringValue* options=voptions.get_hash()) { |
| int valid_options=0; | int valid_options=0; |
| Line 251 static void _sql(Request& r, MethodParam | Line 261 static void _sql(Request& r, MethodParam |
| static void keys_collector( | static void keys_collector( |
| HashStringValue::key_type key, | HashStringValue::key_type key, |
| HashStringValue::value_type value, | HashStringValue::value_type, |
| Table *table) { | Table *table) { |
| Table::element_type row(new ArrayString); | Table::element_type row(new ArrayString); |
| *row+=new String(key, String::L_TAINTED); | *row+=new String(key, String::L_TAINTED); |
| *table+=row; | *table+=row; |
| } | } |
| static void _keys(Request& r, MethodParams* ) { | static void _keys(Request& r, MethodParams&) { |
| Table::columns_type columns(new ArrayString); | Table::columns_type columns(new ArrayString); |
| *columns+=new String("key"); | *columns+=new String("key"); |
| Table* table=new Table(columns); | Table* table=new Table(columns); |
| Line 267 static void _keys(Request& r, MethodPara | Line 277 static void _keys(Request& r, MethodPara |
| r.write_no_lang(*new VTable(table)); | r.write_no_lang(*new VTable(table)); |
| } | } |
| static void _count(Request& r, MethodParams* ) { | static void _count(Request& r, MethodParams&) { |
| r.write_no_lang(*new VInt(GET_SELF(r, VHash).hash().count())); | r.write_no_lang(*new VInt(GET_SELF(r, VHash).hash().count())); |
| } | } |
| static void _delete(Request& r, MethodParams* params) { | static void _delete(Request& r, MethodParams& params) { |
| GET_SELF(r, VHash).hash().remove(params->as_string(0, "key must be string")); | GET_SELF(r, VHash).hash().remove(params.as_string(0, "key must be string")); |
| } | } |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| Line 306 static void one_foreach_cycle( | Line 316 static void one_foreach_cycle( |
| } | } |
| info->r->write_pass_lang(sv_processed); | info->r->write_pass_lang(sv_processed); |
| } | } |
| static void _foreach(Request& r, MethodParams* params) { | static void _foreach(Request& r, MethodParams& params) { |
| Foreach_info info; | Foreach_info info={ |
| info.r=&r; | &r, |
| info.key_var_name=¶ms->as_string(0, "key-var name must be string"); | ¶ms.as_string(0, "key-var name must be string"), |
| info.value_var_name=¶ms->as_string(1, "value-var name must be string"); | ¶ms.as_string(1, "value-var name must be string"), |
| info.body_code=¶ms->as_junction(2, "body must be code"); | ¶ms.as_junction(2, "body must be code"), |
| info.delim_maybe_code=params->count()>3?params->get(3):0; | params.count()>3?params.get(3):0, |
| info.vkey=new VString; | /*vkey=*/new VString, |
| false | |
| }; | |
| VHash& self=GET_SELF(r, VHash); | VHash& self=GET_SELF(r, VHash); |
| HashStringValue& hash=self.hash(); | HashStringValue& hash=self.hash(); |