001/* 002 * Copyright (c) 2015-2023 Tada AB and other contributors, as listed below. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the The BSD 3-Clause License 006 * which accompanies this distribution, and is available at 007 * http://opensource.org/licenses/BSD-3-Clause 008 * 009 * Contributors: 010 * Chapman Flack 011 */ 012package org.postgresql.pljava.example.annotation; 013 014import org.postgresql.pljava.annotation.SQLAction; 015 016/** 017 * Test of a very simple form of conditional execution in the deployment 018 * descriptor using only the {@code <implementor name>} specified for an 019 * {@code <implementor block>}. 020 * <p> 021 * When a deployment descriptor is executed, the config setting 022 * {@code pljava.implementors} determines which {@code <implementor block>}s 023 * will be executed (in addition to all of the plain {@code <SQL statement>}s 024 * that are not tagged with an implementor name). The default setting of 025 * {@code pljava.implementors} is simply {@code postgresql}. 026 * <p> 027 * In this example, an SQLAction (with the default implementor name PostgreSQL 028 * so it should always execute) tests some condition and, based on the result, 029 * adds {@code LifeIsGood} to the list of recognized implementor names. 030 * <p> 031 * Later SQLActions with that implementor name should also be executed, while 032 * those with a different, unrecognized implementor should not. 033 * <p> 034 * That is what happens at <em>deployment</em> (or undeployment) time, when the 035 * jar has been loaded into the target database and the deployment descriptor is 036 * being processed. 037 * <p> 038 * The {@code provides} and {@code requires} attributes matter at 039 * <em>compile</em> time: they are hints to the DDR generator so it will be sure 040 * to write the SQLAction that tests the condition ahead of the ones that 041 * depend on the condition having been tested. The example illustrates that an 042 * SQLAction's {@code implementor} is treated as an implicit {@code requires}. 043 * Unlike an explicit one, it is weak: if there is nothing declared that 044 * {@code provides} it, that's not an error; affected SQLActions will just be 045 * placed as late in the generated DDR as other dependencies allow, in case 046 * something in the preceding actions will be setting those implementor tags. 047 * <p> 048 * The implicit {@code requires} derived from an {@code implementor} is also 049 * special in another way: it does not have its sense reversed when generating 050 * the "undeploy" actions of the deployment descriptor. Ordinary requirements 051 * do, so the dependent objects get dropped before the things they depend on. 052 * But the code for setting a conditional implementor tag has to be placed 053 * ahead of the uses of the tag, whether deploying or undeploying. 054 * <p> 055 * An {@code SQLAction} setting an implementor tag does not need to have any 056 * {@code remove=} actions. If it does not (the usual case), its 057 * {@code install=} actions will be used in both sections of the deployment 058 * descriptor. 059 * <p> 060 * This example adds {@code LifeIsGood} ahead of the prior content of 061 * {@code pljava.implementors}. Simply replacing the value would stop the 062 * default implementor PostgreSQL being recognized, probably not what's wanted. 063 * The final {@code true} argument to {@code set_config} makes the setting 064 * local, so it is reverted when the transaction completes. 065 * <p> 066 * In addition to the goodness-of-life examples, this file also generates 067 * one or more statements setting PostgreSQL-version-based implementor tags that 068 * are relied on by various other examples in this directory. 069 */ 070@SQLAction(provides={"LifeIsGood","LifeIsNotGood"}, install= 071 "SELECT CASE 42 WHEN 42 THEN " + 072 " set_config('pljava.implementors', 'LifeIsGood,' || " + 073 " current_setting('pljava.implementors'), true) " + 074 "ELSE " + 075 " set_config('pljava.implementors', 'LifeIsNotGood,' || " + 076 " current_setting('pljava.implementors'), true) " + 077 "END" 078) 079 080@SQLAction(implementor="LifeIsGood", install= 081 "SELECT javatest.logmessage('INFO', 'ConditionalDDR looking good!')" 082) 083 084@SQLAction(implementor="LifeIsNotGood", install= 085 "SELECT javatest.logmessage('WARNING', " + 086 " 'ConditionalDDR: This should not be executed')" 087) 088 089@SQLAction(provides="postgresql_ge_100000", install= 090 "SELECT CASE WHEN" + 091 " 100000 <= CAST(current_setting('server_version_num') AS integer)" + 092 " THEN set_config('pljava.implementors', 'postgresql_ge_100000,' || " + 093 " current_setting('pljava.implementors'), true) " + 094 "END" 095) 096public class ConditionalDDR { }