libdballe
5.18
|
00001 /* 00002 * dballe/db - Archive for point-based meteorological data 00003 * 00004 * Copyright (C) 2005--2010 ARPA-SIM <urpsim@smr.arpa.emr.it> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 * 00019 * Author: Enrico Zini <enrico@enricozini.com> 00020 */ 00021 00022 #ifndef DBA_DB_H 00023 #define DBA_DB_H 00024 00025 #include <dballe/db/odbcworkarounds.h> 00026 #include <dballe/db/cursor.h> 00027 #include <wreport/varinfo.h> 00028 #include <string> 00029 #include <vector> 00030 #include <memory> 00031 00042 /* Import the attributes. */ 00043 #define DBA_IMPORT_ATTRS 1 00044 /* Attempt to merge pseudoana extra information into the existing ones. */ 00045 #define DBA_IMPORT_FULL_PSEUDOANA 2 00046 /* Import datetime information as data to preserve their attributes. */ 00047 #define DBA_IMPORT_DATETIME_ATTRS 4 00048 /* Message data will overwrite existing values; otherwise, trying to insert 00049 * existing data will cause an error. */ 00050 #define DBA_IMPORT_OVERWRITE 8 00051 /* Perform the import outside of the transaction. This will make the function 00052 * faster but not atomic: if interrupted, for example in case of error, then 00053 * the data inserted before the interruption will stay in the database. */ 00054 #define DBA_IMPORT_NO_TRANSACTIONS 16 00055 00056 00061 #define DBA_DB_WANT_COORDS (1 << 0) 00062 00063 #define DBA_DB_WANT_IDENT (1 << 1) 00064 00065 #define DBA_DB_WANT_LEVEL (1 << 2) 00066 00067 #define DBA_DB_WANT_TIMERANGE (1 << 3) 00068 00069 #define DBA_DB_WANT_DATETIME (1 << 4) 00070 00071 #define DBA_DB_WANT_VAR_NAME (1 << 5) 00072 00073 #define DBA_DB_WANT_VAR_VALUE (1 << 6) 00074 00075 #define DBA_DB_WANT_REPCOD (1 << 7) 00076 00077 #define DBA_DB_WANT_ANA_ID (1 << 8) 00078 00079 #define DBA_DB_WANT_CONTEXT_ID (1 << 9) 00080 00086 #define DBA_DB_MODIFIER_BEST (1 << 0) 00087 00090 #define DBA_DB_MODIFIER_BIGANA (1 << 1) 00091 00092 #define DBA_DB_MODIFIER_DISTINCT (1 << 2) 00093 00094 #define DBA_DB_MODIFIER_ANAEXTRA (1 << 3) 00095 00096 #define DBA_DB_MODIFIER_NOANAEXTRA (1 << 4) 00097 00098 #define DBA_DB_MODIFIER_UNSORTED (1 << 5) 00099 00103 #define DBA_DB_MODIFIER_STREAM (1 << 6) 00104 00105 #define DBA_DB_MODIFIER_SORT_FOR_EXPORT (1 << 7) 00106 00107 namespace dballe { 00108 struct Record; 00109 struct Msg; 00110 struct Msgs; 00111 struct MsgConsumer; 00112 00113 namespace db { 00114 struct Connection; 00115 struct Statement; 00116 struct Sequence; 00117 struct Repinfo; 00118 struct Station; 00119 struct Context; 00120 struct Data; 00121 struct Attr; 00122 } 00123 00127 class DB 00128 { 00129 public: 00131 db::Connection* conn; 00132 00133 protected: 00142 struct db::Repinfo* m_repinfo; 00144 struct db::Station* m_station; 00146 struct db::Context* m_context; 00148 struct db::Data* m_data; 00150 struct db::Attr* m_attr; 00154 db::Statement* stm_last_insert_id; 00156 DBALLE_SQL_C_SINT_TYPE m_last_insert_id; 00157 00165 db::Sequence* seq_station; 00167 db::Sequence* seq_context; 00170 void init_after_connect(); 00171 00175 void run_sql(const char* query); 00176 00180 void drop_table_if_exists(const char* name); 00181 00185 void drop_sequence_if_exists(const char* name); 00186 00191 void fill_ana_layer(Msg& msg, int id_station, int id_report); 00192 00193 public: 00194 DB(); 00195 ~DB(); 00196 00212 void connect(const char* dsn, const char* user, const char* password); 00213 00222 void connect_generic(const char* config); 00223 00230 void connect_from_file(const char* pathname); 00231 00242 void connect_from_url(const char* url); 00243 00250 void connect_test(); 00251 00260 static bool is_url(const char* str); 00261 00263 db::Repinfo& repinfo(); 00264 00266 db::Station& station(); 00267 00269 db::Context& context(); 00270 00272 db::Data& data(); 00273 00275 db::Attr& attr(); 00276 00288 void reset(const char* repinfo_file = 0); 00289 00293 void delete_tables(); 00294 00312 void update_repinfo(const char* repinfo_file, int* added, int* deleted, int* updated); 00313 00317 int rep_cod_from_memo(const char* memo); 00318 00322 const std::string& rep_memo_from_cod(int rep_cod); 00323 00332 bool check_rep_cod(int rep_cod); 00333 00337 int last_station_insert_id(); 00338 00342 int last_context_insert_id(); 00343 00350 int get_rep_cod(Record& rec); 00351 00352 /* 00353 * Lookup, insert or replace data in station taking the values from 00354 * rec. 00355 * 00356 * If rec did not contain ana_id, it will be set by this function. 00357 * 00358 * @param rec 00359 * The record with the station information 00360 * @param can_add 00361 * If true we can insert new stations in the database, if false we 00362 * only look up existing records and raise an exception if missing 00363 * @returns 00364 * The station ID 00365 */ 00366 int obtain_station(Record& rec, bool can_add=true); 00367 00368 /* 00369 * Lookup, insert or replace data in station taking the values from 00370 * rec. 00371 * 00372 * If rec did not contain context_id, it will be set by this function. 00373 * 00374 * @param rec 00375 * The record with the context information 00376 * @returns 00377 * The context ID 00378 */ 00379 int obtain_context(Record& rec); 00380 00397 void insert(Record& rec, bool can_replace, bool station_can_add); 00398 00406 void remove(const Record& rec); 00407 00417 void remove_orphans(); 00418 00434 std::auto_ptr<db::Cursor> query(const Record& query, unsigned int wanted, unsigned int modifiers); 00435 00444 std::auto_ptr<db::Cursor> query_stations(const Record& query); 00445 00458 std::auto_ptr<db::Cursor> query_data(const Record& rec); 00459 00475 unsigned query_attrs(int id_context, wreport::Varcode id_var, const db::AttrList& qcs, Record& attrs); 00476 00489 void attr_insert_or_replace(int id_context, wreport::Varcode id_var, const Record& attrs, bool can_replace); 00490 00504 void attr_insert(int id_context, wreport::Varcode id_var, const Record& attrs); 00505 00518 void attr_insert_new(int id_context, wreport::Varcode id_var, const Record& attrs); 00519 00532 void attr_remove(int id_context, wreport::Varcode id_var, const db::AttrList& qcs); 00533 00548 void import_msg(const Msg& msg, const char* repmemo, int flags); 00549 00564 void import_msgs(const Msgs& msgs, const char* repmemo, int flags); 00565 00575 void export_msgs(const Record& query, MsgConsumer& cons); 00576 00580 void dump(FILE* out); 00581 }; 00582 00583 } // namespace dballe 00584 00585 /* vim:set ts=4 sw=4: */ 00586 #endif