|
|
| version 1.4, 2001/01/29 21:51:52 | version 1.26, 2001/04/05 16:30:42 |
|---|---|
| Line 1 | Line 1 |
| /* | /** @file |
| $Id$ | Parser: table class. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | |
| $Id$ | |
| */ | */ |
| #include <stdlib.h> | #include <stdlib.h> |
| #include "pa_table.h" | #include "pa_table.h" |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_exception.h" | |
| Table::Table(Request& arequest, | Table::Table(Pool& apool, |
| char *afile, uint aline, | const String *aorigin_string, |
| Array *acolumns, | Array *acolumns, |
| int initial_rows) : | int initial_rows) : |
| Array(arequest.pool, initial_rows), | Array(apool, initial_rows), |
| request(arequest), | |
| current(0), | forigin_string(aorigin_string), |
| columns(acolumns), | fcurrent(0), |
| name2number(arequest.pool, false) { | fcolumns(acolumns), |
| #ifndef NO_STRING_ORIGIN | name2number(pool()) { |
| origin.file=afile; | |
| origin.line=aline; | if(fcolumns) |
| #endif | for(int i=0; i<fcolumns->size(); i++) { |
| const String& name=*fcolumns->get_string(i); | |
| if(columns) | |
| for(int i=0; i<columns->size(); i++) { | |
| String name(pool); | |
| name.APPEND(columns->get_cstr(i), 0, 0); | |
| name2number.put(name, i+1); | name2number.put(name, i+1); |
| } | } |
| } | } |
| const Array *Table::at(int index) { | int Table::column_name2index(const String& column_name) const { |
| if(index<0 || index>=size()) | if(fcolumns) { // named |
| request.operator_error.raise(0, | int column_number=name2number.get_int(column_name); |
| "table column index %d is out of range [0..%d]", | if(column_number) |
| index, size()-1); | return column_number-1; |
| else { | |
| return static_cast<const Array *>(get(index)); | THROW(0, 0, |
| &column_name, | |
| "column not found"); | |
| return 0; // unreached | |
| } | |
| } else { // nameless | |
| char *error_pos=0; | |
| int result=(int)strtol(column_name.cstr(), &error_pos, 0); | |
| if(error_pos && *error_pos) | |
| THROW(0, 0, | |
| &column_name, | |
| "invalid column number"); | |
| return result; | |
| } | |
| } | } |
| const char *Table::item(int index) { | const String *Table::item(int column) const { |
| const Array *row=at(current); | if(valid(fcurrent)) { |
| return row->get_cstr(index); | const Array& row=at(fcurrent); |
| if(column>=0 && column<row.size()) // proper index? | |
| return row.get_string(column); | |
| } | |
| return 0; // it's OK we don't have row|column, just return nothing | |
| } | } |
| const char *Table::item(String& column_name) { | bool Table::locate(int column, const String& value) { |
| int column_index; | for(fcurrent=0; fcurrent<size(); fcurrent++) { |
| if(columns) { | const String *item_value=item(column); |
| int found_index=name2number.get_int(column_name); | if(item_value && *item_value==value) |
| if(found_index) | return true; |
| column_index=found_index-1; | |
| else | |
| request.operator_error.raise(&column_name, "column not found"); | |
| } else { | |
| column_index=atoi(column_name.cstr()); | |
| const Array *row=at(current); | |
| if(column_index<0 || column_index>=row->size()) | |
| request.operator_error.raise(&column_name, | |
| "table column index %d is out of range [0..%d]", | |
| column_index, row->size()-1); | |
| } | } |
| return item(column_index); | fcurrent=0; |
| return false; | |
| } | |
| void Table::shift(int offset) { | |
| if(size()) | |
| fcurrent=(fcurrent+offset+size())%size(); | |
| } | } |