2
The contents of this file are subject to the Initial Developer's Public
3
License Version 1.0 (the "License"); you may not use this file except in
4
compliance with the License. You may obtain a copy of the License here:
5
http://www.flamerobin.org/license.html.
7
Software distributed under the License is distributed on an "AS IS"
8
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9
License for the specific language governing rights and limitations under
12
The Original Code is FlameRobin (TM).
14
The Initial Developer of the Original Code is Milan Babuskov.
15
The function getTriggerType is adapted from Firebird projects isql code
17
Portions created by the original developer
18
are Copyright (C) 2004 Milan Babuskov.
25
// For compilers that support precompilation, includes "wx/wx.h".
26
#include "wx/wxprec.h"
32
// for all others, include the necessary headers (this file is usually all you
33
// need because it includes almost all "standard" wxWindows headers
37
//------------------------------------------------------------------------------
40
#include "metadataitem.h"
44
//------------------------------------------------------------------------------
49
infoIsLoadedM = false;
51
//------------------------------------------------------------------------------
52
bool YTrigger::getTriggerInfo(std::string& object, bool& active, int& position, std::string& type)
54
if (!infoIsLoadedM && !loadInfo())
62
//------------------------------------------------------------------------------
63
bool YTrigger::loadInfo(bool force)
65
infoIsLoadedM = false;
66
YDatabase *d = getDatabase();
69
lastError().setMessage("database not set");
73
IBPP::Database& db = d->getDatabase();
77
IBPP::Transaction tr1 = IBPP::TransactionFactory(db, IBPP::amRead);
79
IBPP::Statement st1 = IBPP::StatementFactory(db, tr1);
81
"select t.rdb$relation_name, t.rdb$trigger_sequence, t.rdb$trigger_inactive, t.rdb$trigger_type "
82
"from rdb$triggers t where rdb$trigger_name = ? "
85
st1->Set(1, getName());
89
st1->Get(2, &positionM);
96
activeM = (temp == 0);
100
triggerTypeM = getTriggerType(ttype);
102
infoIsLoadedM = true;
107
catch (IBPP::Exception &e)
109
lastError().setMessage(e.ErrorMessage());
113
lastError().setMessage("System error.");
118
//------------------------------------------------------------------------------
119
bool YTrigger::getSource(std::string& source) const
121
YDatabase *d = getDatabase();
124
lastError().setMessage("database not set");
128
IBPP::Database& db = d->getDatabase();
132
IBPP::Transaction tr1 = IBPP::TransactionFactory(db, IBPP::amRead);
134
IBPP::Statement st1 = IBPP::StatementFactory(db, tr1);
135
st1->Prepare("select rdb$trigger_source from rdb$triggers where rdb$trigger_name = ?");
136
st1->Set(1, getName());
139
IBPP::Blob b = IBPP::BlobFactory(st1->Database(), st1->Transaction());
142
try // if blob is empty the exception is thrown
143
{ // I tried to check st1->IsNull(1) but it doesn't work
144
b->Open(); // to this hack is the only way (for the time being)
153
char buffer[8192]; // 8K block
156
int size = b->Read(buffer, 8192);
166
catch (IBPP::Exception &e)
168
lastError().setMessage(e.ErrorMessage());
172
lastError().setMessage("System error.");
177
//------------------------------------------------------------------------------
178
std::string YTrigger::getTriggerType(int type)
182
std::vector<std::string> prefix_types, suffix_types;
183
prefix_types.push_back("BEFORE");
184
prefix_types.push_back("AFTER");
186
suffix_types.push_back("");
187
suffix_types.push_back("INSERT");
188
suffix_types.push_back("UPDATE");
189
suffix_types.push_back("DELETE");
191
#define TRIGGER_ACTION_PREFIX(value) ((value + 1) & 1)
192
#define TRIGGER_ACTION_SUFFIX(value, slot) (((value + 1) >> (slot * 2 - 1)) & 3)
195
int prefix = TRIGGER_ACTION_PREFIX(type);
196
result = prefix_types[prefix];
198
int suffix = TRIGGER_ACTION_SUFFIX(type, 1);
199
result += " " + suffix_types[suffix];
200
suffix = TRIGGER_ACTION_SUFFIX(type, 2);
202
result += " OR " + suffix_types[suffix];
203
suffix = TRIGGER_ACTION_SUFFIX(type, 3);
205
result += " OR " + suffix_types[suffix];
208
//------------------------------------------------------------------------------
209
YTrigger::firingTimeType YTrigger::getFiringTime()
213
if (triggerTypeM.substr(0, 6) == "BEFORE")
214
return beforeTrigger;
218
//------------------------------------------------------------------------------
219
std::string YTrigger::getAlterSql()
221
std::string object, source, type;
225
if (!getTriggerInfo(object, active, position, type) || !getSource(source))
226
return lastError().getMessage();
228
std::ostringstream sql;
229
sql << "SET TERM ^ ;\nALTER TRIGGER " << nameM;
233
sql << " INACTIVE\n";
236
sql << position << "\n";
239
sql << "^\nSET TERM ; ^";
242
//------------------------------------------------------------------------------
243
std::string YTrigger::getCreateSqlTemplate() const
245
return "SET TERM ^ ;\n\n"
246
"CREATE TRIGGER name FOR table/view \n"
248
" {BEFORE | AFTER} INSERT OR UPDATE OR DELETE \n"
249
" POSITION number \n"
252
" /* enter trigger code here */ \n"
256
//------------------------------------------------------------------------------
257
const std::string YTrigger::getTypeName() const
261
//------------------------------------------------------------------------------