libdballe 5.10
db.h
Go to the documentation of this file.
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 std::vector<wreport::Varcode>& 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 std::vector<wreport::Varcode>& 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