9 #include "CoralBase/AttributeSpecification.h"
10 #include "CoralBase/AttributeList.h"
11 #include "CoralBase/Attribute.h"
12 #include "CoralBase/Exception.h"
13 #include "RelationalAccess/IConnectionService.h"
14 #include "RelationalAccess/ISessionProxy.h"
15 #include "RelationalAccess/ITable.h"
16 #include "RelationalAccess/TableDescription.h"
17 #include "RelationalAccess/ITableDataEditor.h"
18 #include "RelationalAccess/ITransaction.h"
19 #include "RelationalAccess/ISchema.h"
20 #include "RelationalAccess/IQuery.h"
21 #include "RelationalAccess/ICursor.h"
22 #include "RelationalAccess/SchemaException.h"
24 #include "CoolKernel/IFolder.h"
25 #include "CoolKernel/IFieldSpecification.h"
26 #include "CoolKernel/FolderSpecification.h"
38 cool::IDatabasePtr cooldb,
39 coral::IConnectionService& coralsvc,
40 const bool readonly) :
49 m_log << coral::Error <<
"Cannot derive CORAL connection string from: "
52 "CoraCoolDatabase::CoraCoolDatabase");
54 m_log << coral::Debug <<
"CORAL dbconnection string is: " <<
m_dbconn
66 m_log << coral::Error <<
"Exception caught: " <<
e.what() <<
86 std::string::size_type
c1=coolstr.find(
':');
87 if (
c1!=std::string::npos) {
89 techno=coolstr.substr(0,
c1);
90 std::string::size_type
c2;
92 if (
c2==std::string::npos)
c2=coolstr.size();
94 c1=coolstr.find(
"schema=");
95 if (
c1!=std::string::npos) {
96 c2=coolstr.find(
';',
c1+7);
97 if (
c2==std::string::npos)
c2=coolstr.size();
100 c1=coolstr.find(
"dbname=");
101 if (
c1!=std::string::npos) {
102 c2=coolstr.find(
';',
c1+7);
103 if (
c2==std::string::npos)
c2=coolstr.size();
107 if (techno==
"oracle" || techno==
"mysql" || techno==
"frontier") {
116 }
else if (techno==
"sqlite") {
124 c1=coolstr.find(
'/');
125 if (
c1!=std::string::npos) {
132 m_log << coral::Debug <<
"Extracted CORAL connection string: " <<
m_dbconn
133 <<
" and database name: " <<
m_dbname <<
" with status " << dbok <<
139 const cool::IRecordSpecification&
spec) {
141 unsigned int n=
spec.size();
142 for (
unsigned int i=0;
i<
n;++
i) {
143 const cool::IFieldSpecification&
field=
spec[
i];
153 const std::string&
spec) {
154 m_log << coral::Debug <<
"Store AttrList specification for table " <<
157 const std::string attrtable=
m_dbname+
"_CORACOOLATTR";
158 coral::ITable*
table;
160 table=&(
m_proxy->nominalSchema().tableHandle(attrtable));
162 catch (coral::SchemaException&
e) {
164 coral::TableDescription tdesc(attrtable);
165 tdesc.setName(attrtable);
166 tdesc.insertColumn(
"NAME",
"string",31,
false);
167 tdesc.insertColumn(
"ATTRSPEC",
"string",4000,
false);
168 tdesc.setPrimaryKey(
"NAME");
171 m_proxy->transaction().commit();
173 m_proxy->transaction().start(
false);
174 table=&(
m_proxy->nominalSchema().tableHandle(attrtable));
183 data.extend<std::string>(
"NAME");
184 data.extend<std::string>(
"ATTRSPEC");
185 data[0].data<std::string>()=tablename;
187 coral::ITableDataEditor& editor=
table->dataEditor();
188 editor.insertRow(
data);
190 catch (coral::SchemaException&
e) {
191 m_log << coral::Error <<
"Could not insert " << tablename <<
" into "
192 << attrtable <<
" exception: " <<
e.what() <<
200 const std::string& coraltable,
201 const cool::IRecordSpecification& fkspec,
202 const cool::IRecordSpecification& payloadspec,
203 const std::string& coralfk,
204 const std::string& coralpk,
207 const bool createParents) {
211 "CORAL tablename too long (max 18 chars)",
212 "CoraCoolDatabase::createFolder");
215 std::string::size_type
p1,
p2;
219 if (
p1!=std::string::npos &&
p2!=std::string::npos) {
224 newdesc+=
"<coracool>";
227 newdesc+=fkspec[0].name();
232 newdesc+=
"</coracool>";
233 m_log << coral::Debug <<
"Created new description: " << newdesc <<
239 m_proxy->transaction().start(
false);
241 if (coralfk!=coralpk)
248 "CoraCoolDatabase::createFolder");
252 m_log << coral::Debug <<
"Generate CORAL table:" << coraltable <<
254 coral::TableDescription tdesc(
"CoraCoolPayload");
255 tdesc.setName(
m_dbname+
"_"+coraltable);
256 for (
unsigned int i=0;
i<payloadspec.size();++
i) {
257 const cool::IFieldSpecification&
field=payloadspec[
i];
259 if (
field.storageType()==cool::StorageType::Blob64k)
maxsize=0;
260 const std::string typen=coral::AttributeSpecification::typeNameForId(
261 field.storageType().cppType());
262 m_log << coral::Debug <<
"Insert column " <<
field.name() <<
263 " of type " << typen << std::endl;
267 tdesc.setPrimaryKey(coralpk);
269 if (coralfk!=coralpk)
270 tdesc.createIndex(
m_dbname+
"_"+coraltable+
"F",coralfk,
false);
272 m_proxy->nominalSchema().createTable(tdesc);
273 m_proxy->transaction().commit();
291 m_log << coral::Debug <<
"Disconnect/reconnect COOL connection" <<
298 cool::FolderSpecification(
mode,fkspec),newdesc,createParents);
318 if (!
m_cooldb->existsFolder(coolfolder)) {
324 std::string tablename,keycolcool,fkeycolcoral,pkeycolcoral;
326 keycolcool,fkeycolcoral,pkeycolcoral);
331 std::string& tablename,
332 std::string& keycolcool,
333 std::string& fkeycolcoral,
334 std::string& pkeycolcoral) {
343 p1=folderdesc.find(
"<coracool>");
344 p2=folderdesc.find(
"</coracool>");
345 if (
p1==std::string::npos ||
p2==std::string::npos)
return false;
347 c1=folderdesc.find(
':',
p1+10);
348 if (
c1==std::string::npos)
return false;
349 c2=folderdesc.find(
':',
c1+1);
350 if (
c2==std::string::npos)
return false;
354 tablename.append(folderdesc,
p1+10,
c1-
p1-10);
355 keycolcool=folderdesc.substr(
c1+1,
c2-
c1-1);
356 fkeycolcoral=folderdesc.substr(
c2+1,
p2-
c2-1);
358 c3=folderdesc.find(
':',
c2+1);
359 if (
c3!=std::string::npos) {
360 fkeycolcoral=folderdesc.substr(
c2+1,
c3-
c2-1);
361 pkeycolcoral=folderdesc.substr(
c3+1,
p2-
c3-1);
363 fkeycolcoral=folderdesc.substr(
c2+1,
p2-
c2-1);
364 pkeycolcoral=fkeycolcoral;
379 catch (cool::Exception&
e) {
383 std::string tablename,keycolcool,fkeycolcoral,pkeycolcoral;
385 fkeycolcoral,pkeycolcoral)) {
386 m_log << coral::Debug <<
"Drop CORAL payload table " << tablename
390 m_proxy->transaction().start(
false);
391 m_proxy->nominalSchema().dropIfExistsTable(tablename);
395 if (fkeycolcoral!=pkeycolcoral) {
401 bindvar.extend<std::string>(
"SNAME");
402 bindvar[0].data<std::string>()=tablename;
403 coral::ITable&
table=
m_proxy->nominalSchema().tableHandle(
405 long rows=
table.dataEditor().deleteRows(
"NAME=:SNAME",bindvar);
406 if (
rows!=1)
m_log << coral::Error <<
"Unexpected number of rows "
407 <<
rows <<
" with key " << tablename <<
409 m_proxy->transaction().commit();