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 { }