/* * Copyright (c) 2004-2013 Tada AB and other contributors, as listed below. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the The BSD 3-Clause License * which accompanies this distribution, and is available at * http://opensource.org/licenses/BSD-3-Clause * * Contributors: * Tada AB */ package org.postgresql.pljava.example; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.logging.Logger; import org.postgresql.pljava.SessionManager; import org.postgresql.pljava.TriggerData; import org.postgresql.pljava.TriggerException; /** * This class contains some triggers that I found written in C under the * contrib/spi directory of the postgres source distribution. Code to create the * necessary tables, functions, triggers, and some code to actually execute them * can be found in class {@code org.postgresql.pljava.test.Tester} (no longer * part of the build, see under {@code src/java/test}). * * @author Thomas Hallgren */ public class Triggers { public static void afterUsernameInsert(TriggerData td) throws SQLException { Logger log = Logger.getAnonymousLogger(); log.info("After username insert, oid of tuple = " + td.getNew().getInt("oid")); } public static void afterUsernameUpdate(TriggerData td) throws SQLException { Logger log = Logger.getAnonymousLogger(); if (td.isFiredForStatement()) throw new TriggerException(td, "can't process STATEMENT events"); if (td.isFiredBefore()) throw new TriggerException(td, "must be fired after event"); if (!td.isFiredByUpdate()) throw new TriggerException(td, "can't process DELETE or INSERT events"); ResultSet _new = td.getNew(); String[] args = td.getArguments(); if (args.length != 1) throw new TriggerException(td, "one argument was expected"); String colName = args[0]; ResultSet _old = td.getOld(); log.info("Old name is \"" + _old.getString(colName) + '"'); log.info("New name is \"" + _new.getString(colName) + '"'); } /** * insert user name in response to a trigger. */ public static void insertUsername(TriggerData td) throws SQLException { if (td.isFiredForStatement()) throw new TriggerException(td, "can't process STATEMENT events"); if (td.isFiredAfter()) throw new TriggerException(td, "must be fired before event"); if (td.isFiredByDelete()) throw new TriggerException(td, "can't process DELETE events"); ResultSet _new = td.getNew(); String[] args = td.getArguments(); if (args.length != 1) throw new TriggerException(td, "one argument was expected"); if (_new.getString(args[0]) == null) _new.updateString(args[0], SessionManager.current().getUserName()); } public static void leakStatements(TriggerData td) throws SQLException { StringBuffer buf = new StringBuffer(); buf.append("Trigger "); buf.append(td.getName()); buf.append(" declared on table "); buf.append(td.getTableName()); buf.append(" was fired "); if (td.isFiredAfter()) buf.append("after"); else buf.append("before"); buf.append(' '); if (td.isFiredByDelete()) buf.append("delete"); else if (td.isFiredByInsert()) buf.append("insert"); else buf.append("update"); if (td.isFiredForEachRow()) buf.append(" on each row"); // DON'T DO LIKE THIS!!! Connection, PreparedStatement, and ResultSet // instances // should always be closed. // int max = Integer.MIN_VALUE; Connection conn = DriverManager .getConnection("jdbc:default:connection"); PreparedStatement stmt = conn .prepareStatement("SELECT base FROM setReturnExample(?, ?)"); stmt.setInt(1, 5); stmt.setInt(2, 8); ResultSet rs = stmt.executeQuery(); while (rs.next()) { int base = rs.getInt(1); if (base > max) max = base; } buf.append(" reports max = " + max); stmt = conn .prepareStatement("INSERT INTO javatest.mdt (idesc) VALUES (?)"); stmt.setString(1, buf.toString()); stmt.executeUpdate(); } /** * Update a modification time when the row is updated. */ public static void moddatetime(TriggerData td) throws SQLException { if (td.isFiredForStatement()) throw new TriggerException(td, "can't process STATEMENT events"); if (td.isFiredAfter()) throw new TriggerException(td, "must be fired before event"); if (!td.isFiredByUpdate()) throw new TriggerException(td, "can only process UPDATE events"); ResultSet _new = td.getNew(); String[] args = td.getArguments(); if (args.length != 1) throw new TriggerException(td, "one argument was expected"); _new.updateTimestamp(args[0], new Timestamp(System.currentTimeMillis())); } }