Diff for /parser3/src/classes/table.C between versions 1.208 and 1.218

version 1.208, 2005/06/06 08:45:11 version 1.218, 2005/11/25 10:23:51
Line 1 Line 1
 /** @file  /** @file
         Parser: @b table parser class.          Parser: @b table parser class.
   
         Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2005 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 * const IDENT_TABLE_C="$Date$";  static const char * const IDENT_TABLE_C="$Date$";
   
 #include "classes.h"  #include "classes.h"
Line 21  static const char * const IDENT_TABLE_C= Line 20  static const char * const IDENT_TABLE_C=
   
 class MTable: public Methoded {  class MTable: public Methoded {
 public: // VStateless_class  public: // VStateless_class
         Value* create_new_value(Pool&) { return new VTable(); }          Value* create_new_value(Pool&, HashStringValue&) { return new VTable(); }
   
 public:  public:
         MTable();          MTable();
Line 37  DECLARE_CLASS_VAR(table, new MTable, 0); Line 36  DECLARE_CLASS_VAR(table, new MTable, 0);
 // defines for globals  // defines for globals
   
 #define SQL_BIND_NAME "bind"  #define SQL_BIND_NAME "bind"
 #define SQL_LIMIT_NAME "limit"  
 #define SQL_OFFSET_NAME "offset"  
 #define SQL_DEFAULT_NAME "default"  #define SQL_DEFAULT_NAME "default"
 #define SQL_DISTINCT_NAME "distinct"  #define SQL_DISTINCT_NAME "distinct"
 #define TABLE_REVERSE_NAME "reverse"  #define TABLE_REVERSE_NAME "reverse"
Line 46  DECLARE_CLASS_VAR(table, new MTable, 0); Line 43  DECLARE_CLASS_VAR(table, new MTable, 0);
 // globals  // globals
   
 String sql_bind_name(SQL_BIND_NAME);  String sql_bind_name(SQL_BIND_NAME);
 String sql_limit_name(SQL_LIMIT_NAME);  String sql_limit_name(PA_SQL_LIMIT_NAME);
 String sql_offset_name(SQL_OFFSET_NAME);  String sql_offset_name(PA_SQL_OFFSET_NAME);
 String sql_default_name(SQL_DEFAULT_NAME);  String sql_default_name(SQL_DEFAULT_NAME);
 String sql_distinct_name(SQL_DISTINCT_NAME);  String sql_distinct_name(SQL_DISTINCT_NAME);
 String table_reverse_name(TABLE_REVERSE_NAME);  String table_reverse_name(TABLE_REVERSE_NAME);
   
 // local defines  
   
 #define COLUMN_SEPARATOR_NAME "separator"  
 #define COLUMN_ENCLOSER_NAME "encloser"  
   
   
 // methods  // methods
   
 static Table::Action_options get_action_options(Request& r, MethodParams& params,   static Table::Action_options get_action_options(Request& r, MethodParams& params, 
Line 73  static Table::Action_options get_action_ Line 64  static Table::Action_options get_action_
         ]          ]
         but there is ^table.locate[name;value]          but there is ^table.locate[name;value]
   
           ...if(voptions.is_defined() && !voptions.is_string()))
         if(maybe_options.is_string()) { // allow empty options          if(maybe_options.is_string()) { // allow empty options
                 result.defined=true;                  result.defined=true;
                 return result;                  return result;
Line 146  static void _create(Request& r, MethodPa Line 138  static void _create(Request& r, MethodPa
         size_t raw_pos_after=0;          size_t raw_pos_after=0;
         Table::columns_type columns;          Table::columns_type columns;
         if(params.count()==2) {          if(params.count()==2) {
                   const String& snameless=params.as_string(0, "called with two params, first param may only be string 'nameless'");
                   if(snameless!="nameless")
                           throw Exception("parser.runtime",
                                   &snameless,
                                   "table::create called with two params, first param may only be 'nameless'");
                 columns=Table::columns_type(0); // nameless                  columns=Table::columns_type(0); // nameless
         } else {          } else {
                 columns=Table::columns_type(new ArrayString);                  columns=Table::columns_type(new ArrayString);
Line 270  struct TableSeparators { Line 267  struct TableSeparators {
                 column('\t'), scolumn(new String("\t", false)),                  column('\t'), scolumn(new String("\t", false)),
                 encloser(0), sencloser(0)                  encloser(0), sencloser(0)
         {}          {}
         void load( HashStringValue& options ) {          int load( HashStringValue& options ) {
                 if(Value* vseparator=options.get(COLUMN_SEPARATOR_NAME)) {                  int result=0;
                         options.remove(COLUMN_SEPARATOR_NAME);                  if(Value* vseparator=options.get(PA_COLUMN_SEPARATOR_NAME)) {
                         scolumn=&vseparator->as_string();                          scolumn=&vseparator->as_string();
                         if(scolumn->length()!=1)                          if(scolumn->length()!=1)
                                 throw Exception("parser.runtime",                                  throw Exception("parser.runtime",
                                         scolumn,                                          scolumn,
                                         "separator must be one character long");                                          "separator must be one character long");
                         column=scolumn->first_char();                          column=scolumn->first_char();
                           result++;
                 }                  }
                 if(Value* vencloser=options.get(COLUMN_ENCLOSER_NAME)) {                  if(Value* vencloser=options.get(PA_COLUMN_ENCLOSER_NAME)) {
                         options.remove(COLUMN_ENCLOSER_NAME);  
                         sencloser=&vencloser->as_string();                          sencloser=&vencloser->as_string();
                         if(sencloser->length()!=1)                          if(sencloser->length()!=1)
                                 throw Exception("parser.runtime",                                  throw Exception("parser.runtime",
                                         sencloser,                                          sencloser,
                                         "encloser must be one character long");                                          "encloser must be one character long");
                         encloser=sencloser->first_char();                          encloser=sencloser->first_char();
                           result++;
                 }                  }
                   return result;
         }          }
 };  };
   
Line 332  static void _load(Request& r, MethodPara Line 331  static void _load(Request& r, MethodPara
         }          }
                   
         Table& table=*new Table(columns);          Table& table=*new Table(columns);
           int columns_count=columns->count();
   
         // parse cells          // parse cells
         Table::element_type row(new ArrayString);          Table::element_type row(new ArrayString(columns_count));
         skip_empty_and_comment_lines(&data);          skip_empty_and_comment_lines(&data);
         while( lsplit_result sr=lsplit(&data, separators.column, '\n', separators.encloser) ) {          while( lsplit_result sr=lsplit(&data, separators.column, '\n', separators.encloser) ) {
                 if(!*sr.piece && !sr.delim && !row->count()) // append last empty column [if without \n]                  if(!*sr.piece && !sr.delim && !row->count()) // append last empty column [if without \n]
Line 342  static void _load(Request& r, MethodPara Line 342  static void _load(Request& r, MethodPara
                 *row+=new String(sr.piece, 0, true);                  *row+=new String(sr.piece, 0, true);
                 if(sr.delim=='\n') {                  if(sr.delim=='\n') {
                         table+=row;                          table+=row;
                         row=new ArrayString;                          row=new ArrayString(columns_count);
                         skip_empty_and_comment_lines(&data);                          skip_empty_and_comment_lines(&data);
                 }                  }
         }          }
Line 361  static void maybe_enclose( String& to, c Line 361  static void maybe_enclose( String& to, c
                 size_t pos_after=0;                  size_t pos_after=0;
                 for( size_t pos_before; (pos_before=from.pos( encloser, pos_after ))!=STRING_NOT_FOUND; pos_after=pos_before+1) {                  for( size_t pos_before; (pos_before=from.pos( encloser, pos_after ))!=STRING_NOT_FOUND; pos_after=pos_before+1) {
             to<<from.mid(pos_before+1/*+found encloser*/, pos_after-pos_before);              to<<from.mid(pos_before+1/*+found encloser*/, pos_after-pos_before);
                         to<<*sencloser; // doubling encloser                          to<<*sencloser;  to<<*sencloser; // doubling encloser
                 }                  }
                 // last piece                  // last piece
                 size_t from_length=from.length();                  size_t from_length=from.length();
Line 394  static void _save(Request& r, MethodPara Line 394  static void _save(Request& r, MethodPara
         TableSeparators separators;          TableSeparators separators;
         if(param_index<params.count()) {          if(param_index<params.count()) {
                 if(HashStringValue *options=params.as_no_junction(param_index++, "additional params must be hash").get_hash()) {                  if(HashStringValue *options=params.as_no_junction(param_index++, "additional params must be hash").get_hash()) {
                         separators.load(*options);                          int valid_options=separators.load(*options);
                         if(options->count())                          if(valid_options!=options->count())
                                 throw Exception("parser.runtime",                                  throw Exception("parser.runtime",
                                         0,                                          0,
                                         "invalid option passed");                                          "invalid option passed");
Line 447  static void _save(Request& r, MethodPara Line 447  static void _save(Request& r, MethodPara
         }          }
   
         // write          // write
         file_write(r.absolute(file_name),           {
                 sdata.cstr(), sdata.length(), true, do_append);                  const char* data_cstr=sdata.cstr();
                   file_write(r.absolute(file_name), 
                           data_cstr, sdata.length(), true, do_append);
                   if(*data_cstr) // not empty (when empty it's not heap memory)
                           pa_free((void*)data_cstr); // not needed anymore
           }
 }  }
   
 static void _count(Request& r, MethodParams&) {  static void _count(Request& r, MethodParams&) {
Line 477  static void _offset(Request& r, MethodPa Line 482  static void _offset(Request& r, MethodPa
                                         "is invalid whence, valid are 'cur' or 'set'");                                          "is invalid whence, valid are 'cur' or 'set'");
                 }                  }
                                   
                 Value& offset_expr=params.as_junction(params.count()-1, "offset must be expression");                  int offset=params.as_int(params.count()-1, "offset must be expression", r);
                 table.offset(absolute, r.process_to_value(offset_expr).as_int());                  table.offset(absolute, offset);
         } else          } else
                 r.write_no_lang(*new VInt(table.current()));                  r.write_no_lang(*new VInt(table.current()));
 }  }
Line 841  static void _join(Request& r, MethodPara Line 846  static void _join(Request& r, MethodPara
 #ifndef DOXYGEN  #ifndef DOXYGEN
 class Table_sql_event_handlers: public SQL_Driver_query_event_handlers {  class Table_sql_event_handlers: public SQL_Driver_query_event_handlers {
         ArrayString& columns;          ArrayString& columns;
           int columns_count;
         ArrayString* row;          ArrayString* row;
 public:  public:
         Table* table;          Table* table;
Line 861  public: Line 867  public:
         bool before_rows(SQL_Error& error) {           bool before_rows(SQL_Error& error) { 
                 try {                  try {
                         table=new Table(&columns);                          table=new Table(&columns);
                           columns_count=columns.count();
                         return false;                          return false;
                 } catch(...) {                  } catch(...) {
                         error=SQL_Error("exception occured in Table_sql_event_handlers::before_rows");                          error=SQL_Error("exception occured in Table_sql_event_handlers::before_rows");
Line 869  public: Line 876  public:
         }          }
         bool add_row(SQL_Error& error) {          bool add_row(SQL_Error& error) {
                 try {                  try {
                         *table+=row=new ArrayString;                          *table+=row=new ArrayString(columns_count);
                         return false;                          return false;
                 } catch(...) {                  } catch(...) {
                         error=SQL_Error("exception occured in Table_sql_event_handlers::add_row");                          error=SQL_Error("exception occured in Table_sql_event_handlers::add_row");
Line 939  static void _sql(Request& r, MethodParam Line 946  static void _sql(Request& r, MethodParam
         ulong offset=0;          ulong offset=0;
         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_defined() && !voptions.is_string())
                         if(HashStringValue* options=voptions.get_hash()) {                          if(HashStringValue* options=voptions.get_hash()) {
                                 int valid_options=0;                                  int valid_options=0;
                                 if(Value* vbind=options->get(sql_bind_name)) {                                  if(Value* vbind=options->get(sql_bind_name)) {

Removed from v.1.208  
changed lines
  Added in v.1.218


E-mail: