Ilwis-Objects  1.0
GIS and Remote Sensing framework for data access and processing
 All Classes Functions Enumerations Pages
databasetable.h
1 #ifndef DATABASETABLE_H
2 #define DATABASETABLE_H
3 
4 #include "Kernel_global.h"
5 
6 namespace Ilwis {
11 class KERNELSHARED_EXPORT DatabaseTable : public BaseTable
12 {
13 public:
14 
18  DatabaseTable();
19 
30  DatabaseTable(const Resource& resource);
31 
32  ~DatabaseTable();
33 
34  void setDatabase(const QSqlDatabase& base);
35  QSqlDatabase database() const;
36  //@override
37  bool createTable();
38 
39  //@override
40  bool addColumn(const QString &name, const IDomain &domain);
41 
42  //@override
43  bool prepare();
44 
45  //@override
46  bool isValid() const;
47 
55  QString internalName() const;
56 
57  template<class T> bool insertColumn(const QString& col, const QVector<T>& values, const IDomain& dom){
58  if (!dom.isValid()) {
59  kernel()->issues()->log(TR(ERR_INVALID_PROPERTY_IN_4).arg("domain", "table", "column",col));
60  return false;
61  }
62  if ( !_database.isValid()) {
63  kernel()->issues()->log(name(),TR("Database is not initialized"));
64  return false;
65  }
66 
67  QString vt = valueType2DataType(dom->valueType());
68  QString stmt;
69 
70  _columnDefinitionsByName[col] = ColumnDefinition(col,dom,_columns);
71  _columnDefinitionsByIndex = _columnDefinitionsByName[col];
72  _columns++;
73 
74  if ( vt == "Text")
75  stmt = "Insert into %1 (%2) values('?')";
76  else
77  stmt = "Insert into %1 (%2) values(?)";
78  return executeStatement(stmt,col,values);
79 
80  return true;
81 
82  }
83 
84  template<class T> bool updateColumn(const QString& col, const QVector<T>& values){
85  if ( !_database.isValid()) {
86  kernel()->issues()->log(name(),TR("Database is not initialized"));
87  return false;
88  }
89  IDomain dom = _columnDefinitionsByName[col].datadef().domain();
90  if (!dom.isValid()) {
91  kernel()->issues()->log(TR(ERR_INVALID_PROPERTY_IN_4).arg("domain", "table", "column",col));
92  return sUNDEF;
93  }
94  IlwisTypes ty = dom->valueType();
95  QString query = "Update %1 set %2=" ;
96  if ( ty < 256)
97  query += "?";
98  else if ( ty == itSTRING) //TODO: other value cases
99  query = "'?'";
100  return executeStatement(query,col, values);
101  }
102 
103  //@override
104  std::vector<QVariant> record(quint32 n) const ;
105 
106  //@override
107  void record(quint32 rec, const std::vector<QVariant> &vars, quint32 offset=0);
108 
109  //@override
110  std::vector<QVariant> column(const QString& nme, quint32 start=0, quint32 stop=2e9) const;
111 
112  //@override
113  std::vector<QVariant> column(quint32 index, quint32 start=0, quint32 stop=2e9) const;
114 
115  //@override
116  void column(const QString& nme, const std::vector<QVariant>& vars, quint32 offset=0);
117 
118  //@override
119  void column(quint32 index, const std::vector<QVariant> &vars, quint32 offset);
120 
121  //@override
122  QVariant cell(const QString& col, quint32 rec, bool asRaw=true) const;
123 
124  //@override
125  QVariant cell(quint32, quint32 rec, bool asRaw=true) const;
126 
127  //@override
128  void setCell(const QString& col, quint32 rec, const QVariant& inputvar);
129 
130  //@override
131  void setCell(quint32, quint32 rec, const QVariant& var);
132 
138  void drop();
139 
140  //@override
141  IlwisTypes ilwisType() const;
142 
143  //@override
144  std::vector<quint32> select(const QString &conditions) const;
145 
146  //@override
147  IlwisObject *clone();
148 
149  void newRecord();
150 private:
151  QSqlDatabase _database;
152  bool _sqlCreateDone;
153 
154  QString valueType2DataType(IlwisTypes ty) {
155  QString vType=sUNDEF;
156  if ( (ty >= 1024 && ty <= itINT64) || ((ty & itDOMAINITEM) != 0)) {
157  vType = "Integer" ;
158  } else if ( ty >= 1024 &&ty <= itDOUBLE) {
159  vType = "Real";
160  } else if ( ty == itSTRING) {
161  vType = "Text";
162  } else {
163  //TODO: other domain types
164  //TODO: the data types are somewhat dependent on the sql version used by the database
165  //TODO: and at this moment I allow the tables to be connected to external databases though teh default is internal
166  //TODO: it may be an idea to let the connector do a type mapping (textual of course) from a generalized types
167  //TODO: ilwis is probably quite modest in its type use so that should be possible.
168  }
169  return vType;
170  }
171 
172  template<class T> bool executeStatement(const QString& stmt, const QString& col, const QVector<T>& values) {
173  QSqlQuery db(_database);
174  QString query = stmt.arg(internalName(), col);
175  db.prepare(query);
176  QVariantList varlist;
177  for(int i=0 ; i<values.size(); ++i){
178  varlist << values[i];
179  }
180  db.addBindValue(varlist);
181  if (!db.execBatch()) {
182  kernel()->issues()->logSql(db.lastError());
183  return false;
184  }
185 
186  return true;
187  }
188 
189  quint32 numberOfExistingRecords();
190  bool initLoad();
191  void copyTo(IlwisObject *obj);
192 };
194 }
195 
196 
197 
198 #endif // DATABASETABLE_H