2018-10-07 19:40:06 +02:00
|
|
|
|
#include "PgTrigger.h"
|
|
|
|
|
|
#include "PgClassContainer.h"
|
|
|
|
|
|
#include "PgDatabaseCatalog.h"
|
2018-11-18 19:30:45 +01:00
|
|
|
|
#include "PgProcContainer.h"
|
2018-10-07 19:40:06 +02:00
|
|
|
|
#include "SqlFormattingUtils.h"
|
|
|
|
|
|
#include <QStringBuilder>
|
2018-09-23 10:43:32 +02:00
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
QString PgTrigger::objectName() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return name;
|
|
|
|
|
|
}
|
2018-10-07 19:40:06 +02:00
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
QString PgTrigger::dropSql()
|
2018-10-07 19:40:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (m_dropSql.isEmpty()) {
|
2018-11-18 19:30:45 +01:00
|
|
|
|
auto&& fqtablename = genFQTableName(catalog(), *catalog().classes()->getByKey(relid));
|
2018-10-07 19:40:06 +02:00
|
|
|
|
m_dropSql = "DROP TRIGGER " % quoteIdent(name)
|
|
|
|
|
|
% " ON " % fqtablename % ";";
|
|
|
|
|
|
}
|
|
|
|
|
|
return m_dropSql;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
QString PgTrigger::createSql()
|
2018-10-07 19:40:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (m_createSql.isEmpty()) {
|
2018-11-18 19:30:45 +01:00
|
|
|
|
auto&& fqtablename = genFQTableName(catalog(), *catalog().classes()->getByKey(relid));
|
|
|
|
|
|
auto&& triggername = quoteIdent(name);
|
|
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
if (constraint != InvalidOid)
|
|
|
|
|
|
m_createSql += "CREATE CONSTRAINT TRIGGER ";
|
|
|
|
|
|
else
|
|
|
|
|
|
m_createSql += "CREATE TRIGGER ";
|
|
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
m_createSql += triggername + "\n "
|
2018-10-07 19:40:06 +02:00
|
|
|
|
+ typeFireWhen()
|
|
|
|
|
|
+ " " + event();
|
|
|
|
|
|
|
|
|
|
|
|
m_createSql += "\n ON " + fqtablename;
|
|
|
|
|
|
if (deferrable) {
|
|
|
|
|
|
m_createSql += "\n DEFERRABLE INITIALLY ";
|
|
|
|
|
|
if (initdeferred)
|
|
|
|
|
|
m_createSql += "DEFERRED";
|
|
|
|
|
|
else
|
|
|
|
|
|
m_createSql += "IMMEDIATE";
|
|
|
|
|
|
}
|
|
|
|
|
|
m_createSql += "\n FOR EACH " + forEach();
|
|
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
// requires atleast 8.5 don;t think we have to support older
|
|
|
|
|
|
if (!whenclause.isEmpty())
|
|
|
|
|
|
m_createSql += "\n WHEN (" + whenclause + ")";
|
|
|
|
|
|
|
|
|
|
|
|
m_createSql += QString("\n EXECUTE PROCEDURE %1;\n").arg(procedure());
|
|
|
|
|
|
|
|
|
|
|
|
if (!enabled)
|
|
|
|
|
|
m_createSql += QString("ALTER TABLE %1 DISABLE TRIGGER %2;\n").arg(fqtablename, triggername);
|
2018-10-07 19:40:06 +02:00
|
|
|
|
|
|
|
|
|
|
// if (!GetComment().IsEmpty())
|
|
|
|
|
|
// sql += wxT("COMMENT ON TRIGGER ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable()
|
|
|
|
|
|
// + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return m_createSql;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString PgTrigger::typeFireWhen() const
|
2018-09-23 10:43:32 +02:00
|
|
|
|
{
|
2018-10-07 19:40:06 +02:00
|
|
|
|
QString when;
|
2018-09-23 10:43:32 +02:00
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
if (type & TriggerTypeBefore)
|
|
|
|
|
|
when = "BEFORE";
|
|
|
|
|
|
else if (type & TriggerTypeInstead)
|
|
|
|
|
|
when = "INSTEAD OF";
|
|
|
|
|
|
else
|
|
|
|
|
|
when = "AFTER";
|
|
|
|
|
|
return when;
|
2018-09-23 10:43:32 +02:00
|
|
|
|
}
|
2018-10-07 19:40:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString PgTrigger::eventAbbr() const
|
|
|
|
|
|
{
|
|
|
|
|
|
QString event;
|
|
|
|
|
|
if (type & TriggerTypeInsert)
|
|
|
|
|
|
event += "I";
|
|
|
|
|
|
if (type & TriggerTypeUpdate)
|
|
|
|
|
|
event += "U";
|
|
|
|
|
|
if (type & TriggerTypeDelete)
|
|
|
|
|
|
event += "D";
|
|
|
|
|
|
if (type & TriggerTypeTruncate)
|
|
|
|
|
|
event += "T";
|
|
|
|
|
|
return event;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString PgTrigger::event() const
|
|
|
|
|
|
{
|
|
|
|
|
|
QString event;
|
|
|
|
|
|
if (type & TriggerTypeInsert)
|
|
|
|
|
|
event += "INSERT ";
|
|
|
|
|
|
if (type & TriggerTypeUpdate)
|
|
|
|
|
|
event += "UPDATE ";
|
|
|
|
|
|
if (type & TriggerTypeDelete)
|
|
|
|
|
|
event += "DELETE ";
|
|
|
|
|
|
if (type & TriggerTypeTruncate)
|
|
|
|
|
|
event += "TRUNCATE";
|
|
|
|
|
|
return event.trimmed();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString PgTrigger::forEach() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isRow())
|
|
|
|
|
|
return "ROW";
|
|
|
|
|
|
else
|
|
|
|
|
|
return "STATEMENT";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-18 19:30:45 +01:00
|
|
|
|
QString PgTrigger::procedure() const
|
|
|
|
|
|
{
|
|
|
|
|
|
const PgProc *proc = catalog().procs()->getByKey(foid);
|
|
|
|
|
|
QString func_name = proc->fullyQualifiedQuotedObjectName();
|
|
|
|
|
|
return QString("%1(%2)").arg(func_name, arguments());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString PgTrigger::arguments() const
|
|
|
|
|
|
{
|
|
|
|
|
|
QString arglist;
|
|
|
|
|
|
|
|
|
|
|
|
if (nargs > 0)
|
|
|
|
|
|
arglist = args;
|
|
|
|
|
|
|
|
|
|
|
|
QString output;
|
|
|
|
|
|
while (!arglist.isEmpty()) {
|
|
|
|
|
|
int pos = arglist.indexOf(QChar::Null);
|
|
|
|
|
|
if (pos != 0) {
|
|
|
|
|
|
QString arg;
|
|
|
|
|
|
if (pos > 0)
|
|
|
|
|
|
arg = arglist.left(pos);
|
|
|
|
|
|
else
|
|
|
|
|
|
arg = arglist;
|
|
|
|
|
|
|
|
|
|
|
|
if (!output.isEmpty())
|
|
|
|
|
|
output += ", ";
|
|
|
|
|
|
|
|
|
|
|
|
bool conversion_ok = false;
|
|
|
|
|
|
arg.toLongLong(&conversion_ok);
|
|
|
|
|
|
if (conversion_ok)
|
|
|
|
|
|
output += arg;
|
|
|
|
|
|
else
|
|
|
|
|
|
output += escapeLiteral(arg);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
if (!output.isEmpty())
|
|
|
|
|
|
output += ", ";
|
|
|
|
|
|
output += escapeLiteral(QString());
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pos >= 0)
|
|
|
|
|
|
arglist = arglist.mid(pos + 4);
|
|
|
|
|
|
else
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|