diff --git a/database/hsqldb/integration/ant/preprocessor/build.cmd b/database/hsqldb/integration/ant/preprocessor/build.cmd deleted file mode 100644 index 654a7be3..00000000 --- a/database/hsqldb/integration/ant/preprocessor/build.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -@setlocal -..\..\..\build\setenv.cmd -ant -@endlocal diff --git a/database/hsqldb/integration/ant/preprocessor/build.xml b/database/hsqldb/integration/ant/preprocessor/build.xml deleted file mode 100644 index 7c41ecaf..00000000 --- a/database/hsqldb/integration/ant/preprocessor/build.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - Builds the Ant preprocessor integration jar - - Ant version: ${ant.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/ant/preprocessor/sample/ATest.exp b/database/hsqldb/integration/ant/preprocessor/sample/ATest.exp deleted file mode 100644 index c3aad2e6..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/ATest.exp +++ /dev/null @@ -1,13 +0,0 @@ -class ATest { -// JDBC Version is GTE 4: -String msg4 = "I was included because jdbc_version was GTE 4"; -// JDBC Version is GTE 3 and LT 4: -String msg3 = "I was included because jdbc_version was GTE 3 and LT 4"; -// JDBC Version is GTE 2 and LT 3: -String msg2 = "I was included because jdbc_version was GTE 2 and LT 3"; -String s1 = "v1 was defined"; -String s2 = "v2 was defined"; -String s3 = "v1 was \"happy\""; -String s4 = "v2 was \"sad\""; -String s5 = "v1 was less than or equal to v2"; -} diff --git a/database/hsqldb/integration/ant/preprocessor/sample/ATest.src b/database/hsqldb/integration/ant/preprocessor/sample/ATest.src deleted file mode 100644 index 6a1b0bc0..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/ATest.src +++ /dev/null @@ -1,41 +0,0 @@ -class ATest { -//#ifndef jdbc_version -// jdbc_version was not defined: -//#else -//#include Main.inc -//#endinclude -//#endif -//#define jdbc_version 3 -//#include Main.inc -//#endinclude -//#define jdbc_version 2 -//#include Main.inc -//#endinclude -//#define v1 "happy" -//#define v2 "sad" -//#ifdef v1 -String s1 = "v1 was defined"; - //#ifdef v2 -String s2 = "v2 was defined"; - //#if (v1 == "happy") -String s3 = "v1 was \"happy\""; - //#if (v2 == "sad") -String s4 = "v2 was \"sad\""; - //#if (v1 <= v2) -String s5 = "v1 was less than or equal to v2"; - //#else -String s5 = "v1 was greater than v2"; - //#endif (v1 <= v2) - //#else -String s4 = "v2 was not \"sad\""; - //#endif (v2 == "sad") - //#else -String s3 = "v2 was not defined or v1 was not \"happy\""; - //#endif (v1 == "happy") - //#else -String s2 = "v2 was not defined"; - //#endif v1 -//#else -String s1 = "v1 was not defined"; -//#endif v1 -} \ No newline at end of file diff --git a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc2.inc b/database/hsqldb/integration/ant/preprocessor/sample/Jdbc2.inc deleted file mode 100644 index 4157c15f..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc2.inc +++ /dev/null @@ -1 +0,0 @@ -String msg2 = "I was included because jdbc_version was GTE 2 and LT 3"; \ No newline at end of file diff --git a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc3.inc b/database/hsqldb/integration/ant/preprocessor/sample/Jdbc3.inc deleted file mode 100644 index 35127c9b..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc3.inc +++ /dev/null @@ -1 +0,0 @@ -String msg3 = "I was included because jdbc_version was GTE 3 and LT 4"; \ No newline at end of file diff --git a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc4.inc b/database/hsqldb/integration/ant/preprocessor/sample/Jdbc4.inc deleted file mode 100644 index ed2651cd..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/Jdbc4.inc +++ /dev/null @@ -1 +0,0 @@ -String msg4 = "I was included because jdbc_version was GTE 4"; \ No newline at end of file diff --git a/database/hsqldb/integration/ant/preprocessor/sample/Main.inc b/database/hsqldb/integration/ant/preprocessor/sample/Main.inc deleted file mode 100644 index 1a38d52b..00000000 --- a/database/hsqldb/integration/ant/preprocessor/sample/Main.inc +++ /dev/null @@ -1,20 +0,0 @@ -//#if (jdbc_version >= 4) -// JDBC Version is GTE 4: - //#include Jdbc4.inc - // This is where the JDBC 4 stuff will go... - //#endinclude -//#elif (jdbc_version >= 3) -// JDBC Version is GTE 3 and LT 4: - //#include Jdbc3.inc - // This is where the JDBC 3 stuff will go... - //#endinclude -//#elif (jdbc_version >= 2) -// JDBC Version is GTE 2 and LT 3: - //#include Jdbc2.inc - // This is where the JDBC 2 stuff will go... - //#endinclude -//#elif (jdbc_version >= 1) -// JDBC Version is GTE 1 and LT 2: -//#else -// JDBC Version is LT 1: -//#endif \ No newline at end of file diff --git a/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/AntResolver.java b/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/AntResolver.java deleted file mode 100644 index 1797ca45..00000000 --- a/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/AntResolver.java +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2001-2007, The HSQL Development Group - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the HSQL Development Group nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -package org.hsqldb.util.preprocessor.ant; - -import java.io.File; -import org.apache.tools.ant.Project; -import org.hsqldb.util.preprocessor.IResolver; - - -/** - * Resolves properties and paths using an ANT Project. - * - * @author Campbell Burnet (campbell-burnet@users dot sourceforge.net) - * @version 2.6.2 - * @since 1.8.1 - */ -public class AntResolver implements IResolver { - - private final Project project; - - public AntResolver(final Project project) { - this.project = project; - } - - @Override - public String resolveProperties(String expression) { - return this.project.replaceProperties(expression); - } - - @Override - public File resolveFile(String path) { - return this.project.resolveFile(path); - } -} diff --git a/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/PreprocessorAntTask.java b/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/PreprocessorAntTask.java deleted file mode 100644 index a47f7ce5..00000000 --- a/database/hsqldb/integration/ant/preprocessor/src/org/hsqldb/util/preprocessor/ant/PreprocessorAntTask.java +++ /dev/null @@ -1,243 +0,0 @@ -/* Copyright (c) 2001-2022, The HSQL Development Group - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the HSQL Development Group nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -package org.hsqldb.util.preprocessor.ant; - -import java.io.File; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.hsqldb.util.preprocessor.IResolver; -import org.hsqldb.util.preprocessor.Option; -import org.hsqldb.util.preprocessor.Preprocessor; - -/** - *

Provides a facility for invoking the Preprocessor from ANT.

- *

Example ANT target:

{@code 
- *
- *     
- *
- *     
- *     
- *
- * }

Task Attributes

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
NameDescription
srcdir (required)file - directory under which input files are located
targetdir (required)file - directory under which output files are to be written
altext (optional)string - alternate extension to use for output file names.
- * If needed, leading dot should be provided
backup (optional - default: false)boolean - whether to back up pre-existing target files.
- * When true, pre-existing target files are preserved by renaming with - * postfix "~"
encoding (optional)string - the encoding with which to read and write file content.
- * If specified, must be a valid Java encoding identifier, such as "UTF8".
- * When unspecified, the default Java platformn encoding is used.
filter (optional - default: false)boolean - whether to exclude directive lines from output.
indent (optional - default: false)boolean - whether to indent directive lines in output.
symbols (optional)string - CSV list of preprocessor symbols to predefine.
- * When specified, each list element must be of the form:
- * {@code IDENT (ASSIGN? (STRING | NUMBER | IDENT) )?}
- * Note that forward assignments are illegal.
- * See {@link Preprocessor Preprocessor} for details
testonly (optional - default: false)boolean - whether to omit writing output files.
verbose (optional - default: false)boolean - whether to log detailed information.
- * - * @author Campbell Burnet (campbell-burnet@users dot sourceforge.net) - * @version 2.6.2 - * @since 1.8.1 - */ -public class PreprocessorAntTask extends MatchingTask { - - private String ifExpr; - private String unlessExpr; - private File sourceDir; - private File targetDir; - private String defines; - private String altExt; - private String encoding; - private int options = Option.INDENT; - - public void init() { - super.init(); - } - - public void setSrcdir(final File value) { - sourceDir = value; - } - - public void setTargetdir(final File value) { - targetDir = value; - } - - public void setSymbols(final String value) { - defines = value; - } - - public void setVerbose(final boolean verbose) { - options = Option.setVerbose(options, verbose); - } - - public void setBackup(final boolean backup) { - options = Option.setBackup(options, backup); - } - - public void setIndent(final boolean indent) { - options = Option.setIndent(options, indent); - } - - public void setTestonly(final boolean testOnly) { - options = Option.setTestOnly(options, testOnly); - } - - public void setFilter(final boolean filter) { - options = Option.setFilter(options, filter); - } - - public void setAltext(final String ext) { - this.altExt = ext; - } - - public void setEncoding(final String encoding) { - this.encoding = encoding; - } - - public void setIf(final String expr) { - this.ifExpr = expr; - } - - public void setUnless(final String expr) { - this.unlessExpr = expr; - } - - public boolean isActive() { - return (this.ifExpr == null - || getProject().getProperty(this.ifExpr) != null - || this.unlessExpr == null - || getProject().getProperty(this.unlessExpr) == null); - } - - public void execute() throws BuildException { - - if (!isActive()) { - return; - } - - checkSourceDir(); - checkTargetDir(); - - this.sourceDir = getProject().resolveFile("" + this.sourceDir); - - IResolver resolver = new AntResolver(getProject()); - String[] files = getFiles(); - - log("Preprocessing " + files.length + " file(s)"); - - try { - Preprocessor.preprocessBatch(this.sourceDir, this.targetDir, files, - this.altExt, this.encoding, this.options, this.defines, - resolver); - } catch (Exception ex) { - ex.printStackTrace(); - - throw new BuildException("Preprocessing failed: " + ex, - ex); - } - } - - private String[] getFiles() { - return getDirectoryScanner(sourceDir).getIncludedFiles(); - } - - private void checkSourceDir() throws BuildException { - if (this.sourceDir == null) { - throw new BuildException("Source directory is required."); - } - } - - private void checkTargetDir() throws BuildException { - if (targetDir == null) { - throw new BuildException("Target directory is required."); - } - } -} diff --git a/database/hsqldb/integration/extAuthWithSpring/build.xml b/database/hsqldb/integration/extAuthWithSpring/build.xml deleted file mode 100644 index 17c56c5c..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/build.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - You must set Ant property 'authentication.mode' to either - "LDAP" or "JAAS" or "HsqldbSlave" or "JAAS_LDAP". - - Ant property 'hsqldb.jarfile' is required. - To get it using Ivy, SEE COMMENTS THE BUILD FILE. - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/ivy-projsetup.xml b/database/hsqldb/integration/extAuthWithSpring/ivy-projsetup.xml deleted file mode 100644 index 77d5b5ec..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/ivy-projsetup.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -Add Ivy jar file to Ant CLASSPATH. -Copy-and-paste this for any Bourne shell (inc. Bash): - - export ANT_ARGS; ANT_ARGS='-lib ${basedir}/../../build/ivy-2.2.0.jar -noclasspath' - -OR copy-and-paste this for any CMD-like Windows shell: - - SET ANT_ARGS=-lib "${basedir}/../../build/ivy-2.2.0.jar" -noclasspath - - diff --git a/database/hsqldb/integration/extAuthWithSpring/ivy.xml b/database/hsqldb/integration/extAuthWithSpring/ivy.xml deleted file mode 100644 index 1c8cb6e0..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/ivy.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/ivysettings.xml b/database/hsqldb/integration/extAuthWithSpring/ivysettings.xml deleted file mode 100644 index 0b94e7c4..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/ivysettings.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/jul.properties b/database/hsqldb/integration/extAuthWithSpring/jul.properties deleted file mode 100644 index 279bd895..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/jul.properties +++ /dev/null @@ -1,21 +0,0 @@ -# $Id: jul.properties 3914 2010-11-26 22:11:10Z unsaved $ - -# As this is a Java .properties file, use ISO-8859-1 encoding for any -# extended characters. - -# See http://java.sun.com/javase/6/docs/technotes/guides/logging/overview.html -# for an overview of the JDK logging system, aka the Java Logging API or -# java.util.logging. -# If you want more, and easier, control, particularly over the format of -# output records, use Log4J instead. - -# This is different from the default logging file provided by HyperSQL. -# Here, we purposefully turn up verbosity of the org.hsqldb.sample classes so -# the user can see what is going in the examples. - -handlers=java.util.logging.ConsoleHandler -.level=WARNING - -java.util.logging.ConsoleHandler.level=INFO -java.util.logging.ConsoleHandler.formatter=org.hsqldb.lib.BasicTextJdkLogFormatter -org.hsqldb.sample.level=INFO diff --git a/database/hsqldb/integration/extAuthWithSpring/readme.txt b/database/hsqldb/integration/extAuthWithSpring/readme.txt deleted file mode 100644 index 4d8f02be..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/readme.txt +++ /dev/null @@ -1,37 +0,0 @@ -$Id: readme.txt 3931 2010-12-06 05:10:50Z unsaved $ - -This is the home directory of the extAuthWithSpring sample. - -It uses Spring to declaratively configure external authentication with a -master HyperSQL catalog, or with an LDAP server. - -You will need Ant and a Java JDK installed. To get started, invoke - - ant -Dauthentication.mode=HsqldbSlave - -from this directory to run a JDBC app backed by an application database, with -authentication to the application database through another embedded master -database. Play with the Spring bean files in the resources subdirectory to -switch the application database or the masterdatabase, or anything else. - -To play with a JAAS module, run - - ant -Dauthentication.mode=JAAS - -The file resources/jaas.cfg will be generated the first time that you run -anything with Ant. With mode set to "JAAS", the "demo" application -configuration in jaas.cfg will be used. - -If you have an LDAP server, edit "resources/ldapbeans.xml" to set settings -according to your LDAP server then run ant with the authentication.mode set to -"LDAP". -To help determine and test the settings that will work with your LDAP server, I -recommend that you use the program org.hsqldb.auth.LdapAuthBean. See the -HyperSQL API Spec for org.hsqldb.auth.LdapAuthBean and the sample properties -file for it at "sample/ldap-exerciser.properties" in your HyperSQL distribution. - -As an alternative to LDAP mode, you can use JAAS_LDAP mode. That works very -similarly, but uses Sun's JAAS LDAP module and suffers from its limitations. -It should be easy to figure out how to use by looking over the "sunLdap" -application settings in jaas.cfg, and the Spring bean definitions in -resources/jaasldapbeans.xml. diff --git a/database/hsqldb/integration/extAuthWithSpring/resources/beandefs.xml b/database/hsqldb/integration/extAuthWithSpring/resources/beandefs.xml deleted file mode 100644 index 72dc8ac2..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/resources/beandefs.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/resources/jaasbeans.xml b/database/hsqldb/integration/extAuthWithSpring/resources/jaasbeans.xml deleted file mode 100644 index 7dfc310a..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/resources/jaasbeans.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/resources/jaasldapbeans.xml b/database/hsqldb/integration/extAuthWithSpring/resources/jaasldapbeans.xml deleted file mode 100644 index ec865386..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/resources/jaasldapbeans.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/resources/ldapbeans.xml b/database/hsqldb/integration/extAuthWithSpring/resources/ldapbeans.xml deleted file mode 100644 index dcd9278f..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/resources/ldapbeans.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/resources/slavebeans.xml b/database/hsqldb/integration/extAuthWithSpring/resources/slavebeans.xml deleted file mode 100644 index d41ea009..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/resources/slavebeans.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/JdbcAppClass.java b/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/JdbcAppClass.java deleted file mode 100644 index 252f1870..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/JdbcAppClass.java +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2001-2010, The HSQL Development Group - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the HSQL Development Group nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -package org.hsqldb.sample; - -import java.sql.SQLException; -import java.sql.ResultSet; -import java.sql.Connection; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import javax.sql.DataSource; - -/** - * An application class that performs some simple JDBC work. - * - * This class is purposefully not Spring-aware. - */ -public class JdbcAppClass { - private static Log log = LogFactory.getLog(JdbcAppClass.class); - - private boolean initialized; - private DataSource ds; - - public void init() { - if (ds == null) throw new IllegalStateException( - "Required property 'dataSource' not set"); - initialized = true; - } - - public void setDataSource(DataSource ds) { - this.ds = ds; - } - - public void doJdbcWork() throws SQLException { - if (!initialized) - throw new IllegalStateException(JdbcAppClass.class.getName() - + " instance not initialized"); - Connection c = null; - ResultSet rs = null; - try { - c = ds.getConnection(); - rs = c.createStatement().executeQuery("SELECT * FROM t1"); - if (!rs.next()) { - log.error("App class failed to retrieve data from catalog"); - return; - } - if (rs.getInt(1) != 456) { - log.error("App class retrieved wrong value: " + rs.getInt(1)); - return; - } - if (rs.next()) { - log.error("App class failed too much data from catalog"); - return; - } - } finally { - if (c != null) try { - c.rollback(); - } catch (SQLException se) { - // Intentionally empty. - // We have done nothing that we want to commit, but want to - // aggressively free transactional resources. - } - if (rs != null) try { - rs.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - rs = null; // Encourage GC - } - if (c != null) try { - c.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - c = null; // Encourage GC - } - } - log.info("Application Success"); - } -} diff --git a/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/SpringExtAuth.java b/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/SpringExtAuth.java deleted file mode 100644 index 44c40413..00000000 --- a/database/hsqldb/integration/extAuthWithSpring/src/org/hsqldb/sample/SpringExtAuth.java +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (c) 2001-2010, The HSQL Development Group - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the HSQL Development Group nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -package org.hsqldb.sample; - -import java.sql.Connection; -import java.sql.Statement; -import java.sql.DriverManager; -import java.sql.SQLException; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.context.ApplicationContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * As you can tell by the class name, this class is purposefully Spring-aware, - * as it initiates the Spring Spring context load. - * In a web application, a lifecycle lister or other - * mechanism would eliminate the need for any custom Java code to load the - * context (like what we have here). - */ -public class SpringExtAuth { - private static Log log = LogFactory.getLog(SpringExtAuth.class); - - private static final String SYNTAX_MSG = "SYNTAX: " - + SpringExtAuth.class.getName() - + " {LDAP|HsqldbSlave|JAAS|JAAS_LDAP}"; - - /** - * @throws SQLException If Setup of emulation database failed, or if the - * application JDBC work fails. - */ - static public void main(String[] sa) throws SQLException { - if (sa.length != 1) throw new IllegalArgumentException(SYNTAX_MSG); - String authSpringFile = null; - if (sa[0].equals("LDAP")) { - authSpringFile = "ldapbeans.xml"; - } else if (sa[0].equals("JAAS")) { - authSpringFile = "jaasbeans.xml"; - } else if (sa[0].equals("HsqldbSlave")) { - authSpringFile = "slavebeans.xml"; - } else if (sa[0].equals("JAAS_LDAP")) { - authSpringFile = "jaasldapbeans.xml"; - } - if (authSpringFile == null) - throw new IllegalArgumentException(SYNTAX_MSG); - - SpringExtAuth.prepMemoryDatabases(!sa[0].equals("HsqldbSlave")); - ApplicationContext ctx = - new ClassPathXmlApplicationContext("beandefs.xml", authSpringFile); - ListableBeanFactory bf = (ListableBeanFactory) ctx; - JdbcAppClass appBean = bf.getBean("appBean", JdbcAppClass.class); - appBean.doJdbcWork(); - } - - /** - * This method prepares a memory-only catalog. - * After this method runs, a new Connection using the same JDBC URL will - * behave just like connecting to a populated, persistent catalog. - * - * Purposefully not using declarative settings here because this is purely - * emulation setup. - * A real application won't have any method corresponding to this method. - * - * @throws SQLException if setup failed - */ - private static void prepMemoryDatabases(boolean doLdap) - throws SQLException { - Connection c = null; - Statement st = null; - try { - c = DriverManager.getConnection( - "jdbc:hsqldb:mem:localDb", "SA", ""); - // JDBC URL here must match that configured within the bean - // 'appBean' in "beandefs.xml" file - c.setAutoCommit(false); - st = c.createStatement(); - st.executeUpdate("SET DATABASE UNIQUE NAME \"AUTHSAMPLEDBNAME\""); - st.executeUpdate( - "SET DATABASE AUTHENTICATION FUNCTION EXTERNAL NAME " - + "'CLASSPATH:" - + "org.hsqldb.auth.AuthBeanMultiplexer.authenticate'"); - // DB Name here must match that configured in either - // "ldapbeans.xml" or "slavebean.xml", depending on whether you are - // running in LDAP or HsqldbSlave mode, correspondingly. - st.executeUpdate("SET PASSWORD 'SECRET5222173'"); - st.executeUpdate("CREATE TABLE t1(i INTEGER)"); - st.executeUpdate("GRANT SELECT ON t1 TO public"); - st.executeUpdate("INSERT INTO t1 VALUES(456)"); - // Table name and value must match what is expected by method - // JdbcAppClass.doJdbcWork. - c.commit(); - } finally { - if (st != null) try { - st.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - st = null; // Encourage GC - } - if (c != null) try { - c.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - c = null; // Encourage GC - } - } - if (doLdap) return; - - // Create an authentication master database - try { - c = DriverManager.getConnection( - "jdbc:hsqldb:mem:masterDb", "SA", ""); - // JDBC URL here must match that configured for bean - // 'slaveSetup' in "slavebeans.xml" file - c.setAutoCommit(false); - st = c.createStatement(); - st.executeUpdate("SET PASSWORD 'SECRET9123113'"); - // This password will never be used again. - // Changing it from the default just for good security practice. - st.executeUpdate("CREATE USER \"straight\" PASSWORD 'pwd'"); - // User name and password here must match those configured in file - // "beandefs.xml". - c.commit(); - } finally { - if (st != null) try { - st.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - st = null; // Encourage GC - } - if (c != null) try { - c.close(); - } catch (SQLException se) { - log.error("Failed to close emulation database setup Connection", - se); - } finally { - c = null; // Encourage GC - } - } - } -} diff --git a/database/hsqldb/integration/jackrabbit/readme.txt b/database/hsqldb/integration/jackrabbit/readme.txt deleted file mode 100644 index 59f111d9..00000000 --- a/database/hsqldb/integration/jackrabbit/readme.txt +++ /dev/null @@ -1,31 +0,0 @@ -This directory contains access files for Apache Jackrabbit (http://jackrabbit.apache.org/) - -The ddl file for jackrabbit version 2.x is located at: - -resources/org/apache/jackrabbit/core/persistence/bundle/hsqldb.ddl - -This ddl file can be used with the default BundleDbPersistenceManager - -Copy the ddl file to the same directory in your Jackrabbit setup, alongside the existing -ddl files. For example jackrabbit-standalone-2.2.4/org/apache/jackrabbit/core/persistence/bundle - -A sample configuration is given below. The DDL table definitions use BLOBs, which -are stored on disk. - -If you are storing no more than several thousand objects, the non-blob fields can be stored in -memory for quicker access with hsqldb.default_table_type=memory. See the hsqldb documentation -at http://hsqldb.org/doc/2.0/ for different connection URL and other properties that can be used. - - - - - - - - - -A ddl file for older versions of Jackrabbit is also included in the ...core/persistence/db directory. - -All files are modified copies of existing Jackrabbit sources. - - diff --git a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/journal/hsqldb.ddl b/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/journal/hsqldb.ddl deleted file mode 100644 index a9a73d35..00000000 --- a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/journal/hsqldb.ddl +++ /dev/null @@ -1,22 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -create table ${schemaObjectPrefix}JOURNAL (REVISION_ID BIGINT NOT NULL, JOURNAL_ID varchar(255), PRODUCER_ID varchar(255), REVISION_DATA blob) -create unique index ${schemaObjectPrefix}JOURNAL_IDX on ${schemaObjectPrefix}JOURNAL (REVISION_ID) -create table ${schemaObjectPrefix}GLOBAL_REVISION (REVISION_ID BIGINT NOT NULL) -create unique index ${schemaObjectPrefix}GLOBAL_REVISION_IDX on ${schemaObjectPrefix}GLOBAL_REVISION (REVISION_ID) -create table ${schemaObjectPrefix}LOCAL_REVISIONS (JOURNAL_ID varchar(255) NOT NULL, REVISION_ID BIGINT NOT NULL) - -# Inserting the one and only revision counter record now helps avoiding race conditions -insert into ${schemaObjectPrefix}GLOBAL_REVISION VALUES(0) diff --git a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/bundle/hsqldb.ddl b/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/bundle/hsqldb.ddl deleted file mode 100644 index 88cb7465..00000000 --- a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/bundle/hsqldb.ddl +++ /dev/null @@ -1,21 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Bundle persistence DDL script for the HSQLDB database engine (http://www.hsqldb.org) -# -create table ${schemaObjectPrefix}BUNDLE (NODE_ID binary(16) primary key, BUNDLE_DATA blob(2G) not null)) -create table ${schemaObjectPrefix}REFS (NODE_ID binary(16) PRIMARY KEY primary key, REFS_DATA blob(2G) not null)) -create table ${schemaObjectPrefix}BINVAL (BINVAL_ID char(64) PRIMARY KEY, BINVAL_DATA blob(2G) not null) -create table ${schemaObjectPrefix}NAMES (ID INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, NAME varchar(255) not null) diff --git a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/db/hsqldb.ddl b/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/db/hsqldb.ddl deleted file mode 100644 index 7258260c..00000000 --- a/database/hsqldb/integration/jackrabbit/resources/org/apache/jackrabbit/core/persistence/db/hsqldb.ddl +++ /dev/null @@ -1,21 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# DDL script for the HSQLDB database engine (http://www.hsqldb.org) -# -create table ${schemaObjectPrefix}NODE (NODE_ID char(36) primary key, NODE_DATA blob not null) -create table ${schemaObjectPrefix}PROP (PROP_ID varchar(1024) primary key, PROP_DATA blob not null) -create table ${schemaObjectPrefix}REFS (NODE_ID char(36) primary key, REFS_DATA blob not null) -create table ${schemaObjectPrefix}BINVAL (BINVAL_ID varchar(1024) primary key, BINVAL_DATA blob not null) diff --git a/database/hsqldb/integration/readme.txt b/database/hsqldb/integration/readme.txt deleted file mode 100644 index 3dddb51a..00000000 --- a/database/hsqldb/integration/readme.txt +++ /dev/null @@ -1,7 +0,0 @@ -$Id: readme.txt 3900 2010-11-17 03:59:50Z unsaved $ - -Each subdirectory of this directory is a home directory to a sample integration -application. - -See the "readme.txt" file in each subdirectory to see the purpose of that -particular sample. diff --git a/database/hsqldb/sample/StartupParameters.plist b/database/hsqldb/sample/StartupParameters.plist deleted file mode 100644 index c82bb640..00000000 --- a/database/hsqldb/sample/StartupParameters.plist +++ /dev/null @@ -1,21 +0,0 @@ -/* - $Id: StartupParameters.plist 59 2007-04-17 01:08:09Z unsaved $ - Startup Item parameter file that works on at least one Mac OS X system. - - I don't know which of the "Uses" services are available on all Mac's. - I just know that my system has them, and this list causes HSQLDB - to start late enough without resorting to "Latest" (which could cause - problems for people who also start up apps that use HSQLDB). -*/ -{ - Description = "HSQLDB Database Server"; - Provides = ("Hsqldb"); - Requires = ("Resolver"); - Uses = ("Disks", "Network", "Core Services", "TIM", "NetInfo", "Resolver"); - Messages = - { - start = "Starting Hsqldb"; - stop = "Stopping Hsqldb"; - restart = "Restarting Hsqldb"; - }; -} diff --git a/database/hsqldb/sample/acl.txt b/database/hsqldb/sample/acl.txt deleted file mode 100644 index e7d5c3f4..00000000 --- a/database/hsqldb/sample/acl.txt +++ /dev/null @@ -1,31 +0,0 @@ -# $Id: acl.txt 536 2008-12-05 14:55:10Z unsaved $ - -# Sample HyperSQL Network Listener ACL file. -# Specify "allow" and "deny" rules -# For address specifications, individual addresses, host names, and -# network addresses with /bit suffix are allowed, but read the caveat about -# host names below, under the sample "localhost" rule. - -# Blank lines ignored. - # Lines with # as the first non-whitespace character are ignored. - - -allow 2001:db8::/32 -# Allow this 32-bit ipv4 subnet - -allow localhost -# You should use numerical addresses in ACL files, unless you are certain that -# the name will always be known to your network address resolution system -# (assume that you will lose Internet connectivity at some time). -# With a default name resolution setup on UNIX, you are safe to use names -# defined in your /etc/hosts file. - -deny 192.168.101.253 -# Deny a single IP address. -# In our example, 192.168.101.0/24 is our local, organizational network. -# 192.168.101.253 is the IP address of our Intern's PC. -# The Intern does not have permission to access our databases directly. - -allow 192.168.101.0/24 - -# Any ipv4 or ipv6 candidate address not matched above will be denied diff --git a/database/hsqldb/sample/csv-sample.sql b/database/hsqldb/sample/csv-sample.sql deleted file mode 100644 index 90813984..00000000 --- a/database/hsqldb/sample/csv-sample.sql +++ /dev/null @@ -1,65 +0,0 @@ -/* - * $Id: csv-sample.sql 4810 2011-11-20 21:18:10Z unsaved $ - * - * Create a table, CVSV-export the data, import it back. - */ - -* *DSV_COL_DELIM = , -* *DSV_COL_SPLITTER = , --- Following causes a reject report to be written if there are any bad records --- during the import. To test it, enable the "FORCE AN ERROR" block below. -* *DSV_REJECT_REPORT = import.html - --- 1. SETTINGS --- For applications like MS Excel, which can't import or export nulls, we have --- to dummy down our database empty strings to export and import as if they --- were nulls. -* *NULL_REP_TOKEN = - --- Enable following line to quote every cell value --- * *ALL_QUOTED = true - - --- 2. SET UP TEST DATA -CREATE TABLE t (i INT, v VARCHAR(25), d DATE); -INSERT INTO t(i, v, d) VALUES (1, 'one two three', null); -INSERT INTO t(i, v, d) VALUES (2, null, '2007-06-24'); -INSERT INTO t(i, v, d) VALUES (3, 'one,two,,three', '2007-06-24'); -INSERT INTO t(i, v, d) VALUES (4, '"one"two""three', '2007-06-24'); -INSERT INTO t(i, v, d) VALUES (5, '"one,two"three,', '2007-06-24'); -INSERT INTO t(i, v, d) VALUES (6, '', '2007-06-24'); -commit; - --- 3. CSV EXPORT -/* Export */ -\xq t -/* FORCE AN ERROR. Enable the following 3 lines to force a bad CSV record. -\o t.csv -\p barf -\o -*/ - --- 4. BACK UP AND ZERO SOURCE TABLE -CREATE TABLE orig AS (SELECT * FROM t) WITH DATA; -DELETE FROM t; -commit; - --- 5. CSV IMPORT -\mq t.csv -commit; - --- 6. MANUALLY EXAMINE DIFFERENCES BETWEEN SOURCE AND IMPORTED DATA. --- See /testrun/sqltool/csv-roundtrip.sql to see a way to make --- this same comparison programmatically. -* - *NULL_REP_TOKEN -\p -\p ORIGINAL: -SELECT * FROM orig; -\p -\p IMPORTED: -SELECT * FROM t; -\p -\p The empty string in the source table will have been translated to null in -\p the imported data. -\p You can see that the generated CSV file represents both nulls and -\p empty strings as nothing, hence the convergence. diff --git a/database/hsqldb/sample/dsv-sample.sql b/database/hsqldb/sample/dsv-sample.sql deleted file mode 100644 index f9d188e5..00000000 --- a/database/hsqldb/sample/dsv-sample.sql +++ /dev/null @@ -1,37 +0,0 @@ -/* - * $Id: dsv-sample.sql 610 2008-12-22 15:54:18Z unsaved $ - * - * Imports delimiter-separated-values, and generates an output - * reject .dsv file, and a reject report. - * - * To execute, set up a SqlTool database urlid (see User Guide if you don't - * know how to do that); then (from this directory) execute this script like - * - * java ../lib/hsqldb.jar mem dsv-sample.sql - * - * (replace "mem" with your urlid). - */ - -CREATE TABLE sampletable(i INT, d DATE NOT NULL, b BOOLEAN); - -/* If you dont' set *DSV_TARGET_TABLE, it defaults to the base name of the - .dsv file. */ -* *DSV_TARGET_TABLE = sampletable - -\p WARNING: Some records will be skipped, and some others will be rejected. -\p This is on purpose, so you can work with a reject report. -\p - -/* By default, no reject files are written, and the import will abort upon - * the first error encountered. If you set either of these settings, the - * import will continue to completion if at all possible. */ -* *DSV_REJECT_FILE = ${java.io.tmpdir}/sample-reject.dsv -* *DSV_REJECT_REPORT = ${java.io.tmpdir}/sample-reject.html -\m sample.dsv - -/* Enable this line if you want to display all successfully imported data: -SELECT * FROM sampletable; -*/ - -\p -\p See import reject report at '*{*DSV_REJECT_REPORT}'. diff --git a/database/hsqldb/sample/hsqldb.conf b/database/hsqldb/sample/hsqldb.conf deleted file mode 100644 index 9775c745..00000000 --- a/database/hsqldb/sample/hsqldb.conf +++ /dev/null @@ -1,173 +0,0 @@ -# $Id: hsqldb.conf 6310 2021-02-28 15:25:00Z unsaved $ - -# Sample configuration file for HyperSQL Server Listener. -# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide. - -# N.b.!!!! You must place this in the right location for your type of UNIX. -# See the init script "hsqldb" to see where this must be placed and -# what it should be renamed to. - -# This file is "sourced" by a Bourne shell, so use Bourne shell syntax. - -# This file WILL NOT WORK until you set (at least) the non-commented -# variables to the appropriate values for your system. -# Life will be easier if you avoid all filepaths with spaces or any other -# funny characters. Don't ask for support if you ignore this advice. - -# The URLIDS setting below is new and REQUIRED. This setting replaces the -# server.urlid.X settings which used to be needed in your Server's -# properties file. - -# -- Blaine (blaine dot simpson at admc dot com) - -JAVA_EXECUTABLE=/usr/bin/java - -# Unless you copied the jar files from another system, this typically -# resides at $HSQLDB_HOME/lib/sqltool.jar, where $HSQLDB_HOME is your HSQLDB -# software base directory. -# The file name may actually have a version label in it, like -# sqltool-1.2.3.jar (in which case, you must specify the full name here). -# A 'hsqldb.jar' file (with or without version label) must reside in the same -# directory as the specified sqltool.jar file. -SQLTOOL_JAR_PATH=/opt/hsqldb-2.0.0/hsqldb/lib/sqltool.jar -# For the sample value above, there must also exist a file -# /opt/hsqldb-2.0.0/hsqldb/lib/hsqldb*.jar. - -# Where the file "server.properties" or "webserver.properties" resides. -SERVER_HOME=/opt/hsqldb-2.0.0/hsqldb/data - -# What UNIX user the server will run as. -# (The shutdown client is always run as root or the invoker of the init script). -# Runs as root by default, but you should take the time to set database file -# ownerships to another user and set that user name here. -HSQLDB_OWNER=hsqldb - -# The HSQLDB jar file specified in HSQLDB_JAR_PATH above will automatically -# be in the class path. This arg specifies additional classpath elements. -# To embed your own application, add your jar file(s) or class base -# directories here, and add your main class to the INVOC_ADDL_ARGS setting -# below. Another common use-case for adding to your class path is to make -# classes available to the DB engines for SQL/JRT functions and procedures. -#SERVER_ADDL_CLASSPATH=/usr/local/dist/currencybank.jar - -# For startup or shutdown failures, you can save a lot of debugging time by -# temporarily adjusting down MAX_START_SECS and MAX_TERMINATE_SECS to a -# little over what it should take for successful startup and shutdown on -# your system. - -# We require all Server/WebServer instances to be accessible within -# $MAX_START_SECS from when the Server/WebServer is started. -# Defaults to 60. -# Raise this is you are running lots of DB instances or have a slow server. -#MAX_START_SECS=200 - -# Max time to allow for JVM to die after all HSQLDB instances stopped. -# Defaults to 60. Set high because the script will always continue as soon as -# the process has stopped. The importance of this setting is, how long until -# a non-stopping-JVM-problem will be detected. -#MAX_TERMINATE_SECS=0 - -# NEW AND IMPORTANT!!! -# As noted at the top of this file, this setting replaces the old property -# settings server.urlid.X. -# Simply list the URLIDs for all DB instances which your *Server starts. -# Usually, these will exactly mirror the server.database.X settings in your -# server.properties or webserver.properties file. -# Each urlid listed here must be defined to a NETWORK url with Admin privileges -# in the AUTH_FILE specified below. (Network type because we use this for -# inter-process communication) -# Separate multiple values with white space. NO OTHER SPECIAL CHARACTERS! -# Make sure to quote the entire value if it contains white space separator(s). -URLIDS='localhostdb1' - -# These are urlids # ** IN ADDITION TO URLIDS **, for instances which the init -# script should stop but not start. -# Most users will not need this setting. If you need it, you'll know it. -# Defaults to none (i.e., only URLIDS will be stopped). -#SHUTDOWN_URLIDS='ondemand' - -# SqlTool authentication file used only for shutdown. -# The default value will be sqltool.rc in root's home directory, since it is -# root who runs the init script. -# (See the SqlTool chapter of the HyperSQL Utilities Guide if you don't -# understand this). -#AUTH_FILE=/home/blaine/sqltool.rc - -# Typical users will leave this unset and it will default to -# org.hsqldb.server.Server. If you need to run the HSQLDB WebServer class -# instead, due to a firewall or routing impediment, set this to -# org.hsqldb.server.WebServer, see the docs about running WebServr, and -# set up a "webserver.properties" file instead of a "server.properties". -# The JVM that is started can invoke many classes (see the following item -# about that), but this is the server that is used (1) to check status, -# (2) to shut down the JVM. -#TARGET_CLASS=org.hsqldb.server.WebServer - -# This is where you may specify both command-line parameters to TARGET_CLASS, -# plus any number of additional progams to run (along with their command-line -# parameters). The MainInvoker program is used to embed these multiple -# static main invocations into a single JVM, so see the API spec for -# org.hsqldb.util.MainInvoker if you want to learn more. -# N.b. You should only use this setting to set HSQLDB Server or WebServer -# parameters if you run multiple instances of this class, since you can use the -# server/webserver.properties file for a single instance. -# Every additional class (in addition to the TARGET_CLASS) -# must be preceded with an empty string, so that MainInvoker will know -# you are giving a class name. MainInvoker will invoke the normal -# static main(String[]) method of each such class. -# By default, MainInvoker will just run TARGET_CLASS with no args. -# Example that runs just the TARGET_CLASS with the specified arguments: -#INVOC_ADDL_ARGS='-silent false' #but use server.properties property instead! -# Example that runs the TARGET_CLASS plus a WebServer: -#INVOC_ADDL_ARGS='"" org.hsqldb.server.WebServer' -# Note the empty string preceding the class name. -# Example that starts TARGET_CLASS with an argument + a WebServer + -# your own application with its args (i.e., the HSQLDB Servers are -# "embedded" in your application). (Set SERVER_ADDL_CLASSPATH too).: -#INVOC_ADDL_ARGS='-silent false "" org.hsqldb.server.WebServer "" com.acme.Stone --env prod localhost' -# but use server.properties for -silent option instead! -# Example to run a non-TLS server in same JVM with a TLS server. In this -# case, TARGET_CLASS is Server which will run both in TLS mode by virtue of -# setting the tls, keyStore, and keyStorePassword settings in -# server*.properties, as described below; plus an "additional" Server with -# overridden 'tls' and 'port' settings: -#INVOC_ADDL_ARGS="'' org.hsqldb.server.Server --port 9002 --tls false" -# This is an important use case. If you run more than one Server instance, -# you can specify different parameters for each here, even though only one -# server.properties file is supported. -# Note that you use nested quotes to group arguments and to specify the -# empty-string delimiter. - -# The TLS_* settings have been obsoleted. -# To get your server running with TLS, set -# system.javax.net.ssl.keyStore=/path/to/your/private.keystore -# system.javax.net.ssl.keyStorePassword=secretPassword -# server.ssl=true -# IN server.properties or webserver.properties, and -# MAKE THE FILE OWNER-READ-ONLY! -# See the TLS Encryption section of the HyperSQL User Guide, paying attention -# to the security warning(s). -# If you are running with a private server cert, then you will also need to -# set "truststore" in the your SqlTool config file (location is set by the -# AUTH_FILE variable in this file, or it must be at the default location for -# HSQLDB_OWNER). - -# Any JVM args for the invocation of the JDBC client used to verify DB -# instances and to shut them down (SqlToolSprayer). -# Server-side System Properties should normally be set with system.* -# settings in the server/webserver.properties file. -# This example specifies the location of a private trust store for TLS -# encryption. -# For multiple args, put quotes around entire value. -# If you are starting just a TLS_encrypted Listener, you need to uncomment -# this so the init scripts uses TLS to connect. -# If using a private keystore, you also need to set "truststore" settings in -# the sqltool.rc file. -#CLIENT_JVMARGS=-Djavax.net.debug=ssl -# This sample value displays useful debugging information about TLS/SSL. - -# Any JVM args for the server. -# For multiple args, put quotes around entire value. -#SERVER_JVMARGS=-Xmx512m -# You can set the "javax.net.debug" property on the server side here, in the -# same exact way as shown for the client side above. diff --git a/database/hsqldb/sample/hsqldb.init b/database/hsqldb/sample/hsqldb.init deleted file mode 100644 index 2137094d..00000000 --- a/database/hsqldb/sample/hsqldb.init +++ /dev/null @@ -1,501 +0,0 @@ -#!/bin/sh -# For boot-up and system shutdown, most UNIXes explicitly run a shell -# interpreter. In that case, the interpreter line above is ignored. -# There are a few UNIXes (notably Darwin) that require the interpreter line. - -# Copyright (c) 2001-2008, The HSQL Development Group -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# Neither the name of the HSQL Development Group nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, -# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -# $Id: hsqldb.init 6310 2021-02-28 15:25:00Z unsaved $ - -# UNIX init script for HSQLDB. - -# IMPORTANT! Users running multiple HSQLDB ***Server processes*** must use a -# unique "SERVICE" name for each Server process. Most users will run just one -# server instance, possibly serving lots of database instances. Multi-server -# runners must change the value on the following line, and, if your system -# uses chkconfig or insserv, you must change the value of "hsqldb" to the -# same thing (as SERVICE) in the chkconfig and/or insserv blocks a few -# lines down from here (incl. in the pidfile and config file paths). (Sorry -# to say, but you need to repeat this procedure after every HSQLDB upgrade). -SERVICE=hsqldb -# This is the one setting which users will commonly change in this file. -# It's impossible to determine this script name (in a portable way) at boot-up -# time, since ${0} is entirely different for init scripts, depending on UNIX -# version. - -# See the "HyperSQL on UNIX" chapter of the HyperSQL User Guide for how to -# use this file. -# This block only used by chkconfig systems (incl. SuSE Linux). -# chkconfig: 345 87 13 -# description: HyperSQL Database, A High Performance Java Database Server -# pidfile: /run/hsqldb.pid -# config: /etc/sysconfig/hsqldb - -# This block only used by insserv systems (incl. SuSE Linux). -### BEGIN INIT INFO -# Provides: hsqldb -# Required-Start: $syslog $remote_fs $network $named -# Required-Stop: -# Default-Start: 3 5 -# Default-Stop: 0 1 2 6 -# Short-Description: HyperSQL Database Server -# Description: HyperSQL Database, A High Performance Java Database Server -### END INIT INFO - -# UNIX System-V and Linux users should copy this script to the common -# init script directory (/etc/init.d/ on most systems) with name "hsqldb", -# or whatever you have SERVICE set to (no ".init" suffix!). - -# N.b. Being a system script, this script does not use inherited variables. -# If you want to adjust a setting, edit the config file. - -# Strategy of this init script is to avoid shell-specific functionality, -# and use only lowest-common-denominator Bourne capabilities. -# We don't include OS-specific functions, and we don't use shell- -# implementation-specific functionality like "echo ...\c" or "echo -n...". -# Since some Bourne shells don't support shell functions at all, we don't -# even define any local functions. - -# This script has been generalized to the point that it can now "start" -# any combination of classes with the normal static main methods. -# You can supply invocation arguments to the -# TARGET_CLASS invocation, and can start as many other classes as you -# wish by using the INVOC_ADDL_ARGS setting (this includes running -# multiple HSQLDB Servers of various types). - -# Template config file can be obtained from the HyperSQL distribution. -# On the day I write this, I have it located at "sample/hsqldb.cfg" in the -# distro, but that could change. You need to copy then edit it before it -# will work. -# Recommended locations for runtime configuration file: -# Darwin, SunOS, Solaris: /etc/hsqldb.conf -# (However, Sunfreeware.com builds use /usr/local/etc). -# Linux: /etc/hsqldb/hsqldb.conf (works well to put sqltool.rc here too) -# FreeBSD: /usr/local/etc/hsqldb.cfg -# (Replace the base name "hsqldb" with whatever you have SERVICE set to at -# the top of this file). -# You can put it at any of these locations and it will be used. For -# your sanity, only put a file at one of these locations. - -# -- blaine.simpson@admc.com - -set +u - -# Following function is Copyright Apache 2.0 by Axis Data Management Corp. -# and code is copied verbatim from -# http://pub.admc.com/scripts/bin/minsleep-nov.fnc -# Sleeps until process dies or file appears. -# 2nd parameter is assumed to be a PID if it is an integer. -minsleep() { - [ $# -eq 2 ] || { - echo 'SYNTAX: minsleep MAXSECS PID|PATH (for integers MAXSECS and PID)' 1>&2 - return 2 - } - TARGET_PID= TARGET_PATH= - MAXSECS=$1; shift - case "$1" in *[!0-9]*) TARGET_PATH="$1";; *) TARGET_PID="$1";; esac; shift - _secs=0 - while [ $_secs -lt $MAXSECS ]; do - _secs=`expr $_secs + 1` - if [ -n "$TARGET_PID" ]; then - kill -0 $TARGET_PID > /dev/null 2>&1 || return 0 # Target proc died - elif [ -s "$TARGET_PATH" ]; then - return 0 # Target process died - fi - sleep 1 - done - return 1 # Timed out -} - -# This is only used for recursive invocations. -# Will not necessarily be set correctly at system bootup invocations -# (where it is sometimes invoked like "sh... /path/to/hsqldb start"), -# but, in those cases there will be no recursion. -INVOC_PATH=`dirname "$0"` || { - echo "'dirname' failed" 1>&2 - exit 2 -} -[ -n "$INVOC_PATH" ] && INVOC_PATH="${INVOC_PATH}/" - -SYNTAX_MSG="SYNTAX: ${INVOC_PATH}${SERVICE} start|stop|stopcompact|restart|restartcmpacted|status" - -# You can override any of these default values in your config file: - -# Max time for background su command to start up and echo pid. -# (0 works for moderately fast servers). -SU_ECHO_SECS=30 -# File used as semaphore. If file is removed, a running pid checker -# process will exit. -PIDCHECKER_FLAGFILE=/tmp/pidchecker.run -# The following settings get overridden by optional setting in the config file. -# Max time for JVM to die after all HSQLDB instances stopped. -MAX_TERMINATE_SECS=60 -# We require all Server/WebServer instances to be accessible within -# $MAX_START_SECS from when the Server/WebServer is started. -MAX_START_SECS=60 -# Class to start -TARGET_CLASS=org.hsqldb.server.Server - -CLIENT_JVMARGS= -SERVER_JVMARGS= -CFGFILE= -LOGFILE= -PIDFILE= -BASEDIR= -AUTH_FILE= -SHUTDOWN_OPTION= -SERVER_ADDL_CLASSPATH= -INVOC_ADDL_ARGS= -case "`uname`" in - Darwin) # I.e. Mac OS X. I don't know about older Mac OSes. - LOGFILE=/var/log/${SERVICE}.log - PIDFILE=/var/run/${SERVICE}.pid - ;; - Linux) - LOGFILE=/var/log/${SERVICE}.log - PIDFILE=/run/${SERVICE}.pid - ;; - FreeBSD) - LOGFILE=/var/log/${SERVICE}.log - PIDFILE=/var/run/${SERVICE}.pid - ;; - SunOS) - LOGFILE=/var/log/${SERVICE}.log - PIDFILE=/etc/${SERVICE}.pid - ;; - *) - LOGFILE=/var/log/${SERVICE}.log - PIDFILE=/etc/${SERVICE}.pid - ;; -esac - -for candidate in /etc/hsqldb/${SERVICE}.conf \ - /etc/sysconfig/${SERVICE} /etc/${SERVICE}.conf \ - /etc/${SERVICE}.cfg /Library/Hsqldb/conf/${SERVICE}.cfg \ - /Library/Hsqldb/${SERVICE}.cfg /usr/local/etc/${SERVICE}.cfg; do - [ -f $candidate ] && { - CFGFILE=$candidate - break - } -done -[ -n "$CFGFILE" ] || { - echo "No global config file found in any of allowed locations" 1>&2 - exit 11 -} - -# Sanity check -[ -n "$LOGFILE" ] && [ -n "$PIDFILE" ] || { - echo "Internal problem in init script" 1>&2 - exit 11 -} - -[ $# -eq 1 ] || { - echo "$SYNTAX_MSG" 1>&2 - exit 4 -} - -# It would be nice to permit some uses, like "status" by non-root users, -# but for now our goal is a superuser init script. -[ -w / ] || { # Very portable, but perhaps not perfect, test for superuser. - echo "Only 'root' may use this init script" 1>&2 - exit 4 -} - -# Use bsd-style enable/disable if it's in place. -BSDCFG= -[ -r /etc/rc.conf ] && [ -f /etc/rc.conf ] && { - . /etc/rc.conf - BSDCFG=1 -} -[ -r /etc/rc.conf.local ] && [ -f /etc/rc.conf.local ] && { - . /etc/rc.conf.local - BSDCFG=1 -} -[ -n "$BSDCFG" ] && { - case "$hsqldb_enable" in [Yy][Ee][Ss]);; [Oo][Nn]);; [Tt][Rr][Uu][Ee]);; - *) exit 0;; # Don't run if not enabled for BSD startup - esac -} - -COMMAND="$1"; shift - -[ -r "$CFGFILE" ] || { - echo "Unable to read config file '$CFGFILE'" 1>&2 - exit 2 -} -[ -f "$CFGFILE" ] || { - echo "'$CFGFILE' is not a regular file" 1>&2 - exit 2 -} -HSQLDB_OWNER= -JAVA_EXECUTABLE= -SQLTOOL_JAR_PATH= -SERVER_HOME= -SHUTDOWN_URLIDS= -URLIDS= -. "$CFGFILE" -# Suffix delimiter to $SERVER_ADDL_CLASSPATH, if it is set. -[ -n "$SERVER_ADDL_CLASSPATH" ] && -SERVER_ADDL_CLASSPATH="${SERVER_ADDL_CLASSPATH}:" -# Validate that config file sets all required variables. -[ -n "$JAVA_EXECUTABLE" ] && [ -n "$SQLTOOL_JAR_PATH" ] && -[ -n "$SERVER_HOME" ] && [ -n "$URLIDS" ] || { - echo "Config file '$CFGFILE' does not set one or more of following variables - JAVA_EXECUTABLE, SQLTOOL_JAR_PATH, SERVER_HOME, URLIDS" 1>&2 - exit 2 -} -[ -d "$SERVER_HOME" ] || { - echo "SERVER_HOME variable in '$CFGFILE' is set to a non-directory." 1>&2 - exit 2 -} -[ -f "$JAVA_EXECUTABLE" ] && [ -f "$SQLTOOL_JAR_PATH" ] || { - echo "JAVA_EXECUTABLE or SQLTOOL_JAR_PATH in '$CFGFILE' is set to a non-file." 1>&2 - exit 2 -} - -[ -r "$SQLTOOL_JAR_PATH" ] || { - echo "'$SQLTOOL_JAR_PATH' isn't readable" 1>&2 - exit 2 -} -[ -x "$JAVA_EXECUTABLE" ] || { - echo "No Java executable found at '$JAVA_EXECUTABLE'" 1>&2 - exit 2 -} - -# "chown" lives here on some UNIXes. -PATH="$PATH:/usr/sbin" - -# Make a good effort (but not bullet-proof) check on permissions of the -# auth file. Unfortunately, if auth-file is not specified, this depends -# upon both (a) $HOME being set; and (b) SqlToolSprayer and SqlTool defaults. -# On the other hand, it works great if AUTH_FILE is set explicitly by user. -if [ -z "$AUTH_FILE" ] && [ -z "$HOME" ]; then - : # Lousy init environment didn't set $HOME, so can't find dflt cfg file. -else - _AUTH_TEST_PATH="$AUTH_FILE" - [ -n "${_AUTH_TEST_PATH}" ] || _AUTH_TEST_PATH="$HOME/sqltool.rc" - [ -f "$_AUTH_TEST_PATH" ] || { - echo "No auth file found at '$_AUTH_TEST_PATH'" 1>&2 - exit 2 - } - [ -r "$_AUTH_TEST_PATH" ] || { - echo "Auth file '$_AUTH_TEST_PATH' not readable" 1>&2 - exit 2 - } - ls -lLd "$_AUTH_TEST_PATH" | grep '^-..------' > /dev/null 2>&1 || { - echo "Fix permissions on '$_AUTH_TEST_PATH' like 'chmod 600 $_AUTH_TEST_PATH'" 1>&2 - exit 2 - } -fi - -# Set HSQLDB_PID according to pid file. -HSQLDB_PID= -[ -r "$PIDFILE" ] && { - [ -f "$PIDFILE" ] || { - echo "'$PIDFILE' is not a regular file" 1>&2 - exit 6 - } - [ -w "$PIDFILE" ] || { - echo "'$PIDFILE' is not writable" 1>&2 - exit 6 - } - HSQLDB_PID="`cat $PIDFILE`" || { - echo "Failed to read pid file '$PIDFILE'" 1>&2 - exit 6 - } - case "$HSQLDB_PID" in - *[a-zA-Z/!@#$%*+=_~]*) HSQLDB_PID=;; - *'^'*) HSQLDB_PID=;; - esac - [ -n "$HSQLDB_PID" ] || { - echo "Pid file '$PIDFILE' does not contain a valid process identifier" 1>&2 - exit 6 - } - kill -0 "$HSQLDB_PID" > /dev/null 2>&1 || { - echo 'Removing stale pid file' - rm -f "$PIDFILE" || { - echo "Failed to remove pid file '$PIDFILE'" 1>&2 - exit 6 - } - HSQLDB_PID= - } - #echo "PID is ($HSQLDB_PID)" -} - -case "$COMMAND" in - status) - [ -n "$HSQLDB_PID" ] || { - echo "I don't know of any running ${SERVICE} server." - exit 0 - } - echo "There is an ${SERVICE} server loaded from $SQLTOOL_JAR_PATH -running with pid $HSQLDB_PID." - # I would give a nice ps command here, were ps not so damned - # OS-specific. - AUTH_FILE_SWITCH= - # N.b., there will be a problem if there are special characters or - # spaces inside of $AUTH_FILE. - [ -n "$AUTH_FILE" ] && - AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" - # Might as well set CLASSPATH for a cleaner command. - CLASSPATH="$SQLTOOL_JAR_PATH" - export CLASSPATH - export PATH # Required only for some funny init environments. - exec "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ - "-Dsqltoolsprayer.monfile=$PIDFILE" \ - org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null - ;; - start) - [ -n "$TLS_KEYSTORE" ] || [ -n "$TLS_PASSWORD" ] && - echo "WARNING: The TLS_* settings have been obsoleted. -See the comments in the new sample 'hsqldb.cfg' file." 1>&2 - [ -n "$HSQLDB_PID" ] && { - echo "There is already a ${SERVICE} server running with pid $HSQLDB_PID." 1>&2 - exit 1 - } - if [ -n "$HSQLDB_OWNER" ]; then - touch "$PIDFILE" || { - echo "Failed to create pid file" 1>&2 - exit 1 - } - chown "$HSQLDB_OWNER" "$PIDFILE" || { - echo "Failed to chown pid file to '$HSQLDB_OWNER'" 1>&2 - exit 1 - } - # Some OSes choke if there are newlines in this string. - # N.b.!!! The shell of the -c command is the target user's default - # login shell, so keep this command shell-independent! - nohup su "$HSQLDB_OWNER" -c "cd '$SERVER_HOME' && echo "'$$'" > '$PIDFILE' && exec '$JAVA_EXECUTABLE' $SERVER_JVMARGS -classpath '${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}' org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS" >> "$LOGFILE" 2>&1 & - else - cd "$SERVER_HOME" || { - echo "Failed to cd to '$SERVER_HOME'" 1>&2 - exit 1 - } - export JAVA_EXECUTABLE - export SQLTOOL_JAR_PATH - export PIDFILE - export SERVER_JVMARGS - export TARGET_CLASS - export INVOC_ADDL_ARGS - export SERVER_ADDL_CLASSPATH - nohup sh -c ' - echo $$ > "$PIDFILE" || { - echo "Failed to write pid to pid file" 1>&2 - exit 1 - } - eval exec "$JAVA_EXECUTABLE" $SERVER_JVMARGS -classpath "${SERVER_ADDL_CLASSPATH}${SQLTOOL_JAR_PATH}" org.hsqldb.util.MainInvoker $TARGET_CLASS $INVOC_ADDL_ARGS - ' >> "$LOGFILE" 2>&1 & - fi - minsleep $SU_ECHO_SECS "$PIDFILE" - # Make sure bg commands have time to echo pid. - AUTH_FILE_SWITCH= - # N.b., there will be a problem if there are special characters or - # spaces inside of $AUTH_FILE. - [ -n "$AUTH_FILE" ] && - AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" - # Might as well set CLASSPATH for a cleaner command. - CLASSPATH="$SQLTOOL_JAR_PATH" - export CLASSPATH - export PATH # Required only for some funny init environments. - # There are many reasons why we could fail to read the pid file, - # but regardless of why, the pid file does not contain a valid pid. - touch "$PIDCHECKER_FLAGFILE" || { - echo "Failed to touch file '$PIDCHECKER_FLAGFILE'" 1>&2 - exit 1 - } - export PIDCHECKER_FLAGFILE - export PIDFILE - ( - while true; do - # Could possibly use minsleep to simplify this, but I don't - # want to take the time to test the function export behavior. - # -a and -e tests are not portable. - [ -f "$PIDCHECKER_FLAGFILE" ] || exit 0 - kill -0 "`cat $PIDFILE`" > /dev/null 2>&1 || { - rm -f "$PIDFILE" "$PIDCHECKER_FLAGFILE" - exit 1 - } - sleep 1 - done - ) & - "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ - "-Dsqltoolsprayer.monfile=$PIDFILE" \ - "-Dsqltoolsprayer.maxtime=${MAX_START_SECS}000" \ - org.hsqldb.cmdline.SqlToolSprayer 'CALL true;' $URLIDS > /dev/null && { - rm -f "$PIDCHECKER_FLAGFILE" - echo "$TARGET_CLASS started with pid `cat $PIDFILE`" - exit 0 - } - rm -f "$PIDCHECKER_FLAGFILE" - echo "Failed to start $TARGET_CLASS. -See log file '$LOGFILE'." 1>&2 - exit 1 - ;; - stop|stopcompact) - [ "$COMMAND" = stopcompact ] && SHUTDOWN_OPTION='compact' - [ -n "$HSQLDB_PID" ] || { - echo "I don't know of any running ${SERVICE} server." 1>&2 - exit 1 - } - AUTH_FILE_SWITCH= - # N.b., there will be a problem if there are special characters or - # spaces inside of $AUTH_FILE. - [ -n "$AUTH_FILE" ] && - AUTH_FILE_SWITCH="-Dsqltoolsprayer.rcfile=$AUTH_FILE" - # Might as well set CLASSPATH for a cleaner command. - CLASSPATH="$SQLTOOL_JAR_PATH" - export CLASSPATH - export PATH # Required only for some funny init environments. - "$JAVA_EXECUTABLE" $AUTH_FILE_SWITCH $CLIENT_JVMARGS \ - org.hsqldb.cmdline.SqlToolSprayer "shutdown ${SHUTDOWN_OPTION};" \ - $URLIDS $SHUTDOWN_URLIDS || exit 1 - minsleep $MAX_TERMINATE_SECS $HSQLDB_PID || { - echo "WARNING: ${SERVICE} is still running!" 1>&2 - exit 1 - } - rm -f "$PIDFILE" || { - echo "Failed to remove pid file '$PIDFILE'" 1>&2 - exit 1 - } - echo "Successful shutdown ${SHUTDOWN_OPTION} (for the $TARGET_CLASS process)!" - exit 0 - ;; - restart|restartcompacted) - STOP_COMMAND=stop - [ "$COMMAND" = restartcompacted ] && STOP_COMMAND=stopcompact - "${INVOC_PATH}"${SERVICE} $STOP_COMMAND || exit $? - exec "${INVOC_PATH}"/${SERVICE} start - ;; - *) - echo "$SYNTAX_MSG" 1>&2 - exit 5 - ;; -esac diff --git a/database/hsqldb/sample/hsqldb.service b/database/hsqldb/sample/hsqldb.service deleted file mode 100644 index 6fb9e3c6..00000000 --- a/database/hsqldb/sample/hsqldb.service +++ /dev/null @@ -1,34 +0,0 @@ -# $Id: hsqldb.service 6309 2021-02-28 15:06:19Z unsaved $ - -# This file is a systemd init script wrapper for leading-edge UNIXes. -# Copy $HSQLDB_HOME/.../sample/hsqldb.cfg to /etc/hsqldb.conf and edit it. -# Tend to the "TODO" note below. -# Our init script will fail unless your .rc file is protected something like: -# chmod 0600 /path/to/sqltool.rc -# -# To activate this file, run: systemd daemon-reload -# To enable to execute upon system bootups/shutdowns (the ultimate purpose), run: -# systemctl enable hsqldb -# -# -- Blaine (blaine dot simpson at admc dot com) - -[Unit] -Description=HyperSQL Database Server -After=socket.service - -[Service] -# TODO! Change these paths to point to the absolute path of the "hsqldb.init" -# script in your HyperSQL distribution: -ExecStart=/local/hsqldb-2.3.4/sample/hsqldb.init start -ExecReload=/local/hsqldb-2.3.4/sample/hsqldb.init restart -ExecStop=/local/hsqldb-2.3.4/sample/hsqldb.init stop -KillMode=process -#Restart=always Don't silently restart and mask real problems -PIDFile=/run/hsqldb.pid -#User=... We manage user from file /etc/hsqldb.conf -#WorkingDirectory=... No dependency on $PWD -Type=forking -TimeoutStartSec=10 - -[Install] -WantedBy=multi-user.target diff --git a/database/hsqldb/sample/html-report.sql b/database/hsqldb/sample/html-report.sql deleted file mode 100644 index 0cb9bbe9..00000000 --- a/database/hsqldb/sample/html-report.sql +++ /dev/null @@ -1,54 +0,0 @@ -/* - * $Id: html-report.sql 4512 2011-10-11 02:29:08Z unsaved $ - * - * Sample/Template for writing an HTML Report - */ - --- Populate sample data -create table t (i integer, vc varchar(20)); -insert into t values(1, 'one'); -insert into t values(2, 'two'); -insert into t values(3, 'three'); -insert into t values(4, 'four'); -insert into t values(5, 'five'); -commit; - - --- IMPORTANT: \o will append by default. If you want to write a new file, --- it's your responsibility to check that a file of the same name does not --- already exist (or remove it). - - --- Follow the following examples to use your own HTML fragment files. --- * *TOP_HTMLFRAG_FILE = /tmp/top.html --- * *BOTTOM_HTMLFRAG_FILE = /tmp/bottom.html - --- The default TOP_HTMLFRAG_FILE has a reference to this PL variable. -* REPORT_TITLE = Blaine's Sample Report --- The default will also override its CSS style settings with your own if you --- put them in a file named "overrides.css" in same directory alongside your --- reports ("report.html" in this example). --- You can add references to ${system.properties} and *{PL_VARIABLES} in --- your own custom fragment files too. - - --- Turn on HTML output mode. --- Must enable HTML _before_ opening to write top frag. -\h true -\o report.html -\p A message to appear in the Report -SELECT * FROM t; - --- Close off output just to show that you can go back and forth. --- A close with '\o' will not write the bottom boilerplate that closes the HTML. -\o -\h false -\p Some non-HTML non-Report output: -SELECT count(*) FROM t; - -\h true --- Re-open the report -\o report.html -\d t --- This time close it with -\oc diff --git a/database/hsqldb/sample/j-sample.sql b/database/hsqldb/sample/j-sample.sql deleted file mode 100644 index a084d178..00000000 --- a/database/hsqldb/sample/j-sample.sql +++ /dev/null @@ -1,38 +0,0 @@ -/* - $Id: j-sample.sql 3605 2010-06-01 02:21:36Z unsaved $ - Exemplifies use of SqlTool's \j command to specify the JDBC connection - parameters right in the SQL file. - - Invoke like this: - - java -jar .../sqltool.jar - .../j-sample.sql - - (give the file paths to wherever these two files reside). - Or start up SqlTool like this: - - java -jar .../sqltool.jar - - and then execute this script like - - \i .../j-sample.sql -*/ - --- Abort this script when errors occur. --- That's the default if the script is invoked from command-line, but not if --- invoked by \i. -\c false - --- Note the new feature in HyperSQL 2, whereby you can set an SA password --- by just specifying that as the password for the very first connection to --- that database -\j SA fred jdbc:hsqldb:mem:fred --- FORMAT: \j - -\p You have conkected successfully -\p - -CREATE TABLE t(i BIGINT, vc VARCHAR(20)); -INSERT INTO t VALUES(1, 'one'); -INSERT INTO t VALUES(2, 'two'); - -SELECT * FROM t; diff --git a/database/hsqldb/sample/jaas.cfg b/database/hsqldb/sample/jaas.cfg deleted file mode 100644 index cf4d8064..00000000 --- a/database/hsqldb/sample/jaas.cfg +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2010, The HSQL Development Group. All rights reserved. - Released under the HSQL license, available at http://hsqldb.org - - This is a working JAAS configuration file that sets up two "applications" - for use with HyperSQL's extAuthWithSpring sample. - Look under /integration/extAuthWithSpring in your HyperSQL distribution for - details. -*/ - -demo { - /* - * A trivial module that allows access if user name and password start with - * the specified values. - * See source code for the module in for this class under the test-src - * directory of your HyperSQL installation. - */ - org.hsqldb.auth.StartCharModule required - //debug=true - nameStart="s" - pwdStart="p" - ; -}; - -sunLdap { - /* - * JAAS setup for com.sun.security.auth.module.LdapLoginModule. - * This proprietary Sun Java 1.6 JSSE module doesn't support StartTLS, but - * does support the deprecated LDAPS. It also supports only a single role or - * initial schema. - * Do a web search for LdapLoginModule for the API Spec which describes the - * available settings and (incompletely) functionality. There is another - * popular class on the Internet with the same name, so make sure you look at - * the one with package of com.sun.security.auth.module. - */ - com.sun.security.auth.module.LdapLoginModule required - // useSSL means LDAPS, not StartDLS (which is not supported). - // It is true by default, so set to false unless you want LDAPS. - useSSL=false - // Enable following line for debugging - // debug=true - java.naming.security.authentication="DIGEST-MD5" - // Your URL must include the parent DN for user records as shown. - userProvider="ldap://beyla.admc.com/ou=people,dc=admc,dc=com" - authIdentity="{USERNAME}" - userFilter="uid={USERNAME}" - authzIdentity="{memberof}" - ; -}; diff --git a/database/hsqldb/sample/ldap-exerciser.properties b/database/hsqldb/sample/ldap-exerciser.properties deleted file mode 100644 index 95406488..00000000 --- a/database/hsqldb/sample/ldap-exerciser.properties +++ /dev/null @@ -1,44 +0,0 @@ -# $Id: ldap-exerciser.properties 3872 2010-11-09 04:14:40Z unsaved $ - -# This is a sample properties file for the utility program -# org.hsqldb.auth.LdapAuthBean. See the API Spec for -# org.hsqldb.auth.LdapAuthBean for details about all of the settings you can use -# here. - -# IMPORTANT: Use ISO-8859-1 encoding for any extended characters, as you always -# should for a Java properties file. - -# The ${...} construct (for system properties) is not supported. - -# All of these examples use a roleSchemaValuePattern setting to work with the -# LDAP memberOf feature. If you have a direct attribute for specifying roles -# (and optional schema), then just skip that setting. - -# These settings are used for all sample setups -# When startTls is true, ldapHost must match the CN in the server's cert. -ldapHost=beyla.admc.com -parentDn=ou=people,dc=admc,dc=com -roleSchemaValuePattern=cn=([^,]+).* -rolesSchemaAttribute=memberof -accessAttribute=hyperSqlAccess - -# This block of settings works for an OpenLDAP server using the memberOf -# feature for membership in roles, with DIGEST-MD5 SASL and StartTLS with a -# private (non-commercial) SSL certificate. -startTls=true -trustStore=/home/blaine/ca/cacert.store -securityMechanism=DIGEST-MD5 - -# To use an LDAP server that is totally unsecured, comment out the settings in -# the previous block and enable the one setting here. -# An unsecured server can be useful for educational purposes, but not for a -# real application! -#principalTemplate=uid=${username},ou=people,dc=admc,dc=com - -# PLAIN authentication, but StartTLS-encrypted. Disable the block above -# starting with "startTls=true" and enable the settings in this block. -#principalTemplate=uid=${username},ou=people,dc=admc,dc=com - -# SASL DIGEST-MD5 with no encryption. Disable the block above -# starting with "startTls=true" and enable the settings in this block. -#securityMechanism=DIGEST-MD5 diff --git a/database/hsqldb/sample/load_binding_lu.sql b/database/hsqldb/sample/load_binding_lu.sql deleted file mode 100644 index 13be042f..00000000 --- a/database/hsqldb/sample/load_binding_lu.sql +++ /dev/null @@ -1,31 +0,0 @@ -/* - $Id: load_binding_lu.sql 610 2008-12-22 15:54:18Z unsaved $ - Load BINDING Lookup Text Table -*/ - -\p Creating table BINDING_TMPTXT -CREATE TEMP TEXT TABLE binding_tmptxt ( - id integer, - name varchar(12) -); - -\p Setting text file source -SET TABLE binding_tmptxt SOURCE "binding_lu.ttbl;ignore_first=true;fs=|"; - -\p rows in binding_tmptxt: -select count(*) from binding_tmptxt; -\p PRE rows in binding_lu: -select count(*) from binding_lu; - -INSERT INTO binding_lu ( - id, - name -) SELECT - id, - name -FROM BINDING_TMPTXT; - -commit; - -\p POST rows in binding_lu: -select count(*) from binding_lu; diff --git a/database/hsqldb/sample/nullempty.sql b/database/hsqldb/sample/nullempty.sql deleted file mode 100644 index 70c50240..00000000 --- a/database/hsqldb/sample/nullempty.sql +++ /dev/null @@ -1,33 +0,0 @@ -/* - * $Id: nullempty.sql 4709 2011-11-05 01:50:17Z unsaved $ - * - * This sample shows differences between null and empty strings, - * and ? var vs. _/~ variables. - */ - -\p At startup ? is equal to empty string. See between A and B: A*{?}B -* if (A*{?}B == AB) \p ? is the empty string - -CREATE TABLE t(i INTEGER, vc VARCHAR(20)); -INSERT INTO t VALUES(1, 'one'); -INSERT INTO t VALUES(2, 'two'); -* res ~ -SELECT * FROM t; -\p *{?} -\p *{res} -* listvalues ? res - -INSERT INTO t VALUES (3, null); -*res ~ -SELECT vc FROM t WHERE i = 3; -\p *{?} -* if (*res == **NULL) \p res really is null -* listvalues ? res - --- This will prevent SqlTool from aborting when we run a bad SQL statement: -\c true -*res ~ -SELECT hocus FROM pocus; -* if (*? == **NULL) \p ? really is null -* if (*res == **NULL) \p res really is null -* listvalues ? res diff --git a/database/hsqldb/sample/pl.sql b/database/hsqldb/sample/pl.sql deleted file mode 100644 index 3ce8c327..00000000 --- a/database/hsqldb/sample/pl.sql +++ /dev/null @@ -1,95 +0,0 @@ -/* - $Id: pl.sql 4563 2011-10-19 02:24:41Z unsaved $ - SQL File to illustrate the use of some basic SqlTool PL features. - Invoke like - java -jar .../sqltool.jar mem .../pl.sql - -- blaine -*/ - -* if (! *MYTABLE) - \p MYTABLE variable not set! - /* You could use \q to Quit SqlTool, but it's often better to just - break out of the current SQL file. - If people invoke your script from SqlTool interactively (with - \i yourscriptname.sql) any \q will kill their SqlTool session. */ - \p Use argument "-pMYTABLE=mytablename" for SqlTool - * break -* end if - --- Turning on Continue-upon-errors so that we can check for errors ourselves. -\c true - -\p -\p Loading up a table named '*{MYTABLE}'... - -CREATE TABLE *{MYTABLE} ( - i int, - s varchar(20) -); --- PL variable ? is always set to status or fetched value of last SQL --- statement. It will be null/unset if the last SQL statement failed. -\p CREATE status is *{?} -\p - -/* Validate our return status. - In case of success of a CREATE TABLE, *? will be 0, and therefore a - '* if (*?)' would be false. - So we follow the general practice of testing *? for the error indicator - value of null, using the reserved SqlTool system variable *NULL. - */ -* if (*? == *NULL) - \p Our CREATE TABLE command failed. - * break -* end if - --- Default Continue-on-error behavior is what you usually want -\c false -\p - -/* Insert data with a foreach loop. - These values could be from a read of another table or from variables - set on the command line like -*/ -\p Inserting some data into our new table -* foreach VALUE (12 22 24 15) - * if (*VALUE > 23) - \p Skipping *{VALUE} because it is greater than 23 - * continue - \p YOU WILL NEVER SEE THIS LINE, because we just 'continued'. - * end if - INSERT INTO *{MYTABLE} VALUES (*{VALUE}, 'String of *{VALUE}'); -* end foreach -\p - -/* This time instead of using the ? variable, we're assigning the SELECT value - to a User variable, 'themax'. */ -* themax ~ -/* Can put Special Commands and comments between "* VARNAME ~" and the target - SQL statement. */ -\p We're saving the max value for later. You'll still see query output here: -SELECT MAX(i) FROM *{MYTABLE}; - -/* No need to test for failure status (either ? or themax being unset/null), - because we are in \c mode and would have aborted if the SELECT failed. */ -* if (0 == *themax) - \p Got 0 as the max value. - * break - \p YOU WILL NEVER SEE THIS LINE, because we just 'broke'. -* end if - -\p -\p ############################################################## -\p The results of our work: -SELECT * FROM *{MYTABLE}; -\p MAX value is *{themax} - -\p -\p Counting down to exit -* ((i = 3)) -* while (*i > 0) - \p *{i}... - * ((i -= 1)) -- i++ is supported but i-- is not, because -- marks comments -* end while - -\p -\p Everything worked. Signing off. diff --git a/database/hsqldb/sample/plsql.sql b/database/hsqldb/sample/plsql.sql deleted file mode 100644 index 5318697e..00000000 --- a/database/hsqldb/sample/plsql.sql +++ /dev/null @@ -1,44 +0,0 @@ -/* - * $Id: plsql.sql 6375 2021-11-07 17:44:56Z unsaved $ - * - * This example is copied from the "Simple Programs in PL/SQL" - * example by Yu-May Chang, Jeff Ullman, Prof. Jennifer Widom at - * the Standord University Database Group's page - * http://www-db.stanford.edu/~ullman/fcdb/oracle/or-plsql.html . - * I have only removed some blank lines (in case somebody wants to - * copy this code interactively-- because you can't use blank - * lines inside of SQL commands in non-raw mode SqlTool when running - * it interactively); and, at the bottom I have replaced the - * client-specific, non-standard command "run;" with SqlTool's - * corresponding command ".;" and added a plain SQL SELECT command - * to show whether the PL/SQL code worked. - Blaine - */ - -CREATE TABLE T1( - e INTEGER, - f INTEGER -); - -DELETE FROM T1; - -INSERT INTO T1 VALUES(1, 3); - -INSERT INTO T1 VALUES(2, 4); - -/* Above is plain SQL; below is the PL/SQL program. */ -DECLARE - a NUMBER; - b NUMBER; -BEGIN - SELECT e,f INTO a,b FROM T1 WHERE e>1; - INSERT INTO T1 VALUES(b,a); -END; -.; -/** The statement on the previous line, ".;" is SqlTool specific. - * This command says to save the input up to this point to the - * edit buffer and send it to the database server for execution. - * I added the SELECT statement below to give imm - */ - -/* This should show 3 rows, one containing values 4 and 2 (in this order)...*/ -SELECT * FROM t1; diff --git a/database/hsqldb/sample/sample.c b/database/hsqldb/sample/sample.c deleted file mode 100644 index dacc5c4f..00000000 --- a/database/hsqldb/sample/sample.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * @(#)$Id: sample.c 3648 2010-06-08 22:44:25Z unsaved $ - * - * HyperSQL Database Engine - * - * Copyright (c) 2009-2010, The HSQL Development Group - */ - - -#include -#ifdef _WINDOWS -#include -#endif -#include -// sqlext.h pulls in all other ODBC header files that we need -#include -#include - -extern int detectOdbcFailure(SQLRETURN rv, SQLHENV c, char* failMsg); -extern int print_ret(char* msg, int retval); -extern int print2_ret(char* msg, char* msg2, int retval); - -/** - * This test HyperSQL client uses the ODBC DSN "tstdsn" to connect up to a - * HyperSQL server. Just configure your own DSN to use the HyperSQL ODBC - * driver, specifying the HyperSQL server host name, database name, user, - * password, etc. - * - * Sample C program accessing HyperSQL. - * - * ODBC C API ref at - * http://msdn.microsoft.com/en-us/library/ms714562(VS.85).aspx . - * Summary of functions at - * http://msdn.microsoft.com/en-us/library/ms712628(VS.85).aspx - * - * To build on UNIX with unixODBC:

- *     gcc -lodbc -o sample sample.c
- * 
- * - * To build in Windows with MSVC++ (Express variant is free):

- *      cl /nologo /D _WINDOWS /D ODBCVER=0x0351 /c sample.c
- *      link odbc32.lib /nologo /machine:x86 sample.obj /out:sample.exe
- * 
- * - * @author Blaine Simpson (blaine dot simpson at admc dot com) - */ -int main(int argc, char** argv) { - SQLRETURN odbcret; - SQLHENV sqlhenv; - SQLHENV conn; - SQLHSTMT stmt; - char *cp; - long in_idval; - const int cstrmax = 100; - char *in_vcval = malloc(cstrmax); - long out_idval; - char *out_vcval = malloc(cstrmax); - char *out_etimeval = malloc(cstrmax); - SQLLEN ntsval = SQL_NTS; - int detect; - - // I. CONNECT - odbcret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlhenv); - if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO) - return print_ret("Failed to allocate an ODBC environment handle", 1); - - odbcret = - SQLSetEnvAttr(sqlhenv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0); - if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO) - return print_ret("Failed to set ODBC version 3.0", 2); - - odbcret = SQLAllocHandle(SQL_HANDLE_DBC, sqlhenv, &conn); - if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO) - return print_ret("Failed to allocate an ODBC connection handle", 3); - - odbcret = SQLSetConnectAttr( - conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0); - if (odbcret != SQL_SUCCESS && odbcret != SQL_SUCCESS_WITH_INFO) - return print_ret("Failed to allocate an ODBC connection handle", 3); - // May also want to set timeout values in the same way - - // Can override the DSN-defined user name and/or password here: - detect = detectOdbcFailure( - SQLConnect(conn, (SQLCHAR*) "tstdsn", SQL_NTS, (SQLCHAR*) NULL, 0, - (SQLCHAR*) NULL, 0), - conn, "Connection failure"); - if (detect) return detect; - - - // II. PREPARE OBJECTS FOR USE - detect = detectOdbcFailure( - SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt), conn, - "Failed to allocate an ODBC statement handle"); - if (detect) return detect; - - // Just using this char pointer because some non-ANSI compilers won't let - // us declare a char array/pointer here. - cp = "DROP TABLE tsttbl IF EXISTS"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "DROP statement failed"); - if (detect) return detect; - - // Some recent change to the HyperSQL server or to unixODBC - // has made this commit necessary, at least on UNIX. Some other - // transaction control command would probably be more - // appropriate here. - detect = detectOdbcFailure(SQLEndTran(SQL_HANDLE_DBC, conn, SQL_COMMIT), - conn, "COMMIT failed"); - if (detect) return detect; - - cp = "CREATE TABLE tsttbl(\n\ - id BIGINT generated BY DEFAULT AS IDENTITY,\n\ - vc VARCHAR(20),\n\ - entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n\ -)"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "CREATE TABLE statement failed"); - if (detect) return detect; - - detect = detectOdbcFailure(SQLCloseCursor(stmt), conn, - "Failed to close Cursor for re-use"); - if (detect) return detect; - - - // III. INSERT DATA - // Non-parameter INSERT - cp = "INSERT INTO tsttbl (id, vc) values (1, 'one')"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "1st Insertion failed"); - if (detect) return detect; - -#ifdef _WINDOWS - // TODO: PROBLEM with Parameterized INPUT in Windows (works fine on UNIX). - // For some reason, even if we are do a Prepare/Execute (and our - // driver is set to always use server-side Preparation), the client side - // is doing the substitution... and doing a bad Lob of it too. - // Therefore, we do all INSERTs statically for Windows here: - cp = "INSERT INTO tsttbl (id, vc) values (2, 'two')"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "2nd Insertion failed"); - if (detect) return detect; - cp = "INSERT INTO tsttbl (id, vc) values (3, 'three')"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "3rd Insertion failed"); - if (detect) return detect; - cp = "INSERT INTO tsttbl (id, vc) values (4, 'four')"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "4th Insertion failed"); - if (detect) return detect; - cp = "INSERT INTO tsttbl (id, vc) values (5, 'five')"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "5th Insertion failed"); - if (detect) return detect; -#else - // Parameterized INSERT - cp = "INSERT INTO tsttbl (id, vc) values (?, ?)"; - detect = detectOdbcFailure(SQLPrepare(stmt, (SQLCHAR*) cp, SQL_NTS), conn, - "Preparation of Insertion stmt failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, - 0, 0, &in_idval, 0, NULL), conn, - "Bind of 'id' input failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, - 20, 0, in_vcval, cstrmax, &ntsval), conn, - "Bind of 'vc' input failed"); - if (detect) return detect; - - in_idval = 2; - strcpy(in_vcval, "two"); - detect = detectOdbcFailure(SQLExecute(stmt), conn, - "Insertion of 2nd row failed"); - if (detect) return detect; - in_idval = 3; - strcpy(in_vcval, "three"); - detect = detectOdbcFailure(SQLExecute(stmt), conn, - "Insertion of 3rd row failed"); - if (detect) return detect; - in_idval = 4; - strcpy(in_vcval, "four"); - detect = detectOdbcFailure(SQLExecute(stmt), conn, - "Insertion of 4th row failed"); - if (detect) return detect; - in_idval = 5; - strcpy(in_vcval, "five"); - detect = detectOdbcFailure(SQLExecute(stmt), conn, - "Insertion of 5th row failed"); - if (detect) return detect; -#endif - - detect = detectOdbcFailure(SQLEndTran(SQL_HANDLE_DBC, conn, SQL_COMMIT), - conn, "COMMIT failed"); - if (detect) return detect; - - detect = detectOdbcFailure(SQLCloseCursor(stmt), conn, - "Failed to close Cursor for re-use"); - if (detect) return detect; - - - // IV. QUERIES - // Non-Parameter QUERY - cp = "SELECT * FROM tsttbl WHERE id < 3"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "Non-parameter query failed"); - // Would return SQL_NO_DATA if no rows inserted. - // Don't need to bind until before fetches are performed. - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn, - "Bind of 'id' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval), - conn, "Bind of 'vc' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval), - conn, "Bind of 'entrytime' output failed"); - if (detect) return detect; - - while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) { - if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect; - printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval); - } - - detect = detectOdbcFailure(SQLCloseCursor(stmt), conn, - "Failed to close Cursor for re-use"); - if (detect) return detect; - -#if _WINDOWS - // Input parameters not working on Windows. See comment above. - cp = "SELECT * FROM tsttbl WHERE id > 3"; - detect = detectOdbcFailure(SQLExecDirect(stmt, cp, SQL_NTS), conn, - "Non-parameter query failed"); - // Would return SQL_NO_DATA if no rows inserted. - // Don't need to bind until before fetches are performed. - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn, - "Bind of 'id' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval), - conn, "Bind of 'vc' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval), - conn, "Bind of 'entrytime' output failed"); - if (detect) return detect; - - while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) { - if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect; - printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval); - } -#else - - // Parameterized QUERY - cp = "SELECT * FROM tsttbl WHERE id > ?"; - detect = detectOdbcFailure(SQLPrepare(stmt, (SQLCHAR*) cp, SQL_NTS), conn, - "Preparation of Query stmt failed"); - if (detect) return detect; - in_idval = 3; - detect = detectOdbcFailure( - SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, - 0, 0, &in_idval, 0, NULL), conn, - "Bind of 'id' input failed"); - if (detect) return detect; - detect = detectOdbcFailure(SQLExecute(stmt), conn, - "Parameterized query failed"); - // Would return SQL_NO_DATA if no rows selected - // Don't need to bind until before fetches are performed. - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 1, SQL_C_SLONG, &out_idval, 0, NULL), conn, - "Bind of 'id' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 2, SQL_C_CHAR, out_vcval, cstrmax, &ntsval), - conn, "Bind of 'vc' output failed"); - if (detect) return detect; - detect = detectOdbcFailure( - SQLBindCol(stmt, 3, SQL_C_CHAR, out_etimeval, cstrmax, &ntsval), - conn, "Bind of 'entrytime' output failed"); - if (detect) return detect; -#endif - - while ((odbcret = SQLFetch(stmt)) != SQL_NO_DATA) { - if (detectOdbcFailure(odbcret, conn, "Fetch failed")) return detect; - printf("%dl|%s|%s\n", out_idval, out_vcval, out_etimeval); - } - - detect = detectOdbcFailure(SQLCloseCursor(stmt), conn, - "Failed to close Cursor"); - if (detect) return detect; - - SQLDisconnect(conn); - SQLFreeHandle(SQL_HANDLE_DBC, conn); - SQLFreeHandle(SQL_HANDLE_ENV, sqlhenv); - //return print_ret("Success", 0); - return 0; -} - -/** - * Displays error message and prepare for program exit. - */ -int barf(SQLHENV c, char* failMsg) { - char sqlhmsg[200], sqlhstat[10]; - SQLSMALLINT junksmall; - SQLINTEGER errint; - - SQLGetDiagRec(SQL_HANDLE_DBC, c, 1, sqlhstat, &errint, - sqlhmsg, 100, &junksmall); - return print2_ret(failMsg, sqlhmsg, 1); -} - -/** - * Displays error message and prepare for program exit if the given - * rv indicates ODBC failure. - */ -int detectOdbcFailure(SQLRETURN rv, SQLHENV c, char* failMsg) { - if (rv == SQL_SUCCESS || rv == SQL_SUCCESS_WITH_INFO) return 0; - return barf(c, failMsg); -} - -/** - * 2-param wrapper for print2_ret() function. - */ -int print_ret(char* msg, int retval) { - return print2_ret(msg, (char*) NULL, retval); -} - -/** - * Displays message to stderr and returns given value. - * - * Function name here is a hack, because I don't remember how to overload C - * functions (in a portable way). - */ -int print2_ret(char* msg, char* msg2, int retval) { - fputs(msg, stderr); - fputc('\n', stderr); - if (msg2 != NULL) { - fputs(msg2, stderr); - fputc('\n', stderr); - } - return retval; -} diff --git a/database/hsqldb/sample/sample.dsv b/database/hsqldb/sample/sample.dsv deleted file mode 100644 index 4cea4715..00000000 --- a/database/hsqldb/sample/sample.dsv +++ /dev/null @@ -1,16 +0,0 @@ -# Comment lines like this are permitted by default, as are - -# blank lines. Header line follows: -i|d|b - -# Two good rows: -1|2007-01-02|true -2|2007-01-03|false - -# This should cause a parse error: -3|not a date|true - -# This should cause a database error: -4||true - -5|2007-01-04|false diff --git a/database/hsqldb/sample/sample.php b/database/hsqldb/sample/sample.php deleted file mode 100644 index d6fd84d7..00000000 --- a/database/hsqldb/sample/sample.php +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/php5 - diff --git a/database/hsqldb/sample/sample.pl b/database/hsqldb/sample/sample.pl deleted file mode 100644 index a51b2906..00000000 --- a/database/hsqldb/sample/sample.pl +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/perl - -# $Id: sample.pl 3633 2010-06-06 23:56:41Z unsaved $ - -# Sample Perl script accessing HyperSQL through the Perl DBI and DBD/ODBC -# modules. - -# This test HyperSQL client uses the ODBC DSN "tstdsn" to connect up to a -# HyperSQL server. Just configure your own DSN to use the HyperSQL ODBC -# driver, specifying the HyperSQL server host name, database name, user, -# password, etc. - -# Author: Blaine Simpson (blaine dot simpson at admc dot com) - - -use strict; -use DBI; - -use vars qw:$dsn $dbh $sth $row $retval %conAttr:; - -$conAttr{AutoCommit} = 0; - -# In addition to the DSN name, you can override or supply additional DSN -# settings, such as "Uid" and "Pwd"; or define the DSN from scratch, starting -# with Driver. These settings are delimited with "; ". See pyodbc docs. -$dsn = "dbi:ODBC:dsn=tstdsn"; - -#$dbh = DBI->connect($dsn, undef, undef) -$dbh = DBI->connect($dsn, undef, undef, \%conAttr) - or die("Failed to connect: ($DBI::err) $DBI::errstr\n"); - -$dbh->do("DROP TABLE tsttbl IF EXISTS"); -$dbh->do( - "CREATE TABLE tsttbl(\n" - . " id BIGINT generated BY DEFAULT AS IDENTITY,\n" - . " vc VARCHAR(20),\n" - . " entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n" - . ")"); - -# First a simple/non-parameterized Insertion -$retval = $dbh->do("INSERT INTO tsttbl (id, vc) values (1, 'one')"); -die "First insertion inserted $retval rows instead of 1\n" unless $retval eq 1; - -# Now same thing with parameters -$sth = $dbh->prepare("INSERT INTO tsttbl (id, vc) values (?, ?)") - or die("Failed to prepare Insertion statement: ($DBI::err) $DBI::errstr\n"); -$retval = $sth->execute(2, 'two') - or die("2nd insertion failed: ($DBI::err) $DBI::errstr\n"); -die "2nd insertion inserted $retval rows instead of 1\n" unless $retval eq 1; - -# The disabled testa re due to known bug with driver. -# The misleading warnings withe "SQL-HY000" may be ignored. -$retval = $sth->execute(3, 'three'); - #or die("3rd insertion failed: ($DBI::err) $DBI::errstr\n"); -#die "3rd insertion inserted $retval rows instead of 1\n" unless $retval eq 1; -$retval = $sth->execute(4, 'four'); - #or die("4th insertion failed: ($DBI::err) $DBI::errstr\n"); -#die "4th insertion inserted $retval rows instead of 1\n" unless $retval eq 1; -$retval = $sth->execute(5, 'five'); - #or die("5th insertion failed: ($DBI::err) $DBI::errstr\n"); -#die "5th insertion inserted $retval rows instead of 1\n" unless $retval eq 1; -$dbh->commit; - # Some recent change to the HyperSQL server or to unixODBC has made this - # necessary, at least on UNIX. Some other transaction control command - # would probably be more appropriate here. - -# Now a simple/non-parameterized Query -$sth = $dbh->prepare("SELECT * FROM tsttbl WHERE id < 3") - or die("Failed to prepare SELECT statement: ($DBI::err) $DBI::errstr\n"); -$sth->execute() - or die("Execution of non-param. query failed : ($DBI::err) $DBI::errstr\n"); - -while ($row = $sth->fetch()) { - print(join '|', @$row); - print("\n"); -} -$sth->finish(); - -$dbh->do('rollback'); - -# Now a parameterized Query -$sth = $dbh->prepare("SELECT * FROM tsttbl WHERE id > ?") - or die("Failed to prepare SELECT statement: ($DBI::err) $DBI::errstr\n"); -# Use bind_param for variety -$sth->bind_param(1, 3); -$sth->execute() - or die("Exec. of parameterized query failed : ($DBI::err) $DBI::errstr\n"); - -while ($row = $sth->fetch()) { - print(join '|', @$row); - print("\n"); -} -$sth->finish(); - -$dbh->disconnect(); - -exit(0); diff --git a/database/hsqldb/sample/sample.py b/database/hsqldb/sample/sample.py deleted file mode 100644 index 9948a24c..00000000 --- a/database/hsqldb/sample/sample.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/python - -# $Id: sample.py 3633 2010-06-06 23:56:41Z unsaved $ - -# Sample Python script accessing HyperSQL through the Python pyodbc module. - -# This test HyperSQL client uses the ODBC DSN "tstdsn-a" to connect up to a -# HyperSQL server. Just configure your own DSN to use the HyperSQL ODBC -# driver, specifying the HyperSQL server host name, database name, user, -# password, etc. - -# N.b. there is some dependency or bug which requires pyodbc to use the -# ANSI variant of the HyperSQL ODBC Driver. Using the normal Unicode -# variant will generate the following error message when you try to connect: -# pyodbc.Error: ('0', '[0] [unixODBC]c (202) (SQLDriverConnectW)') -# It is quite possible that this issue will be taken care of when we fix a -# high-priority bug to do with switching between SQLDriverConnect and -# SQLDriverConnectW on UNIX. - -# Author: Blaine Simpson (blaine dot simpson at admc dot com) - -import pyodbc - -# Get a connection handle. -# In addition to the DSN name, you can override or supply additional DSN -# settings, such as "Uid" and "Pwd"; or define the DSN from scratch, starting -# with Driver. These settings are delimited with "; ". See pyodbc docs. -conn = pyodbc.connect("DSN=tstdsn-a") -try: - conn.autocommit = 0 - - cursor = conn.cursor(); - - cursor.execute("DROP TABLE tsttbl IF EXISTS"); - conn.commit(); # Some recent change to the HyperSQL server or to unixODBC - # has made this necessary, at least on UNIX. Some other - # transaction control command would probably be more - # appropriate here. - - cursor.execute( - "CREATE TABLE tsttbl(\n" - + " id BIGINT generated BY DEFAULT AS IDENTITY,\n" - + " vc VARCHAR(20),\n" - + " entrytime TIMESTAMP DEFAULT current_timestamp NOT NULL\n" - + ")"); - - # First a simple/non-parameterized Insertion - retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (1, 'one')"); - if retval != 1: - raise Exception(('1st insertion inserted ' + repr(retval) - + ' rows instead of 1')) - # Now parameterized. Unfortunately, the Python DB API and pyodbc API do - # not allow re-use of a parsed statement. Cursor must be reparsed for - # each usage. - retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)", - 2, 'two'); - if retval != 1: - raise Exception(('2nd insertion inserted ' + repr(retval) - + ' rows instead of 2')) - retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)", - 3, 'three'); - if retval != 1: - raise Exception(('3rd insertion inserted ' + repr(retval) - + ' rows instead of 3')) - retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)", - 4, 'four'); - if retval != 1: - raise Exception(('4th insertion inserted ' + repr(retval) - + ' rows instead of 4')) - retval = cursor.execute("INSERT INTO tsttbl (id, vc) values (?, ?)", - 5, 'five'); - if retval != 1: - raise Exception(('5th insertion inserted ' + repr(retval) - + ' rows instead of 5')) - conn.commit(); - - # Non-parameterized query - for row in cursor.execute( - "SELECT * FROM tsttbl WHERE id < 3"): - print row - - # Non-parameterized query. As noted above, can't re-use parsed cursor. - for row in cursor.execute( - "SELECT * FROM tsttbl WHERE id > ?", 3): - # For variety, we format the files ourselves this time - print repr(row.ID) + '|' + row.VC + '|' + repr(row.ENTRYTIME) - -except Exception as e: - conn.rollback(); - raise e - -finally: - conn.close(); diff --git a/database/hsqldb/sample/sample.sql b/database/hsqldb/sample/sample.sql deleted file mode 100644 index 0f738e17..00000000 --- a/database/hsqldb/sample/sample.sql +++ /dev/null @@ -1,47 +0,0 @@ -/* - $Id: sample.sql 3605 2010-06-01 02:21:36Z unsaved $ - Exemplifies use of SqlTool. - PCTASK Table creation -*/ - -/* Ignore error for these two statements */ -\c true -DROP TABLE pctasklist; -DROP TABLE pctask; -\c false - -\p Creating table pctask -CREATE TABLE pctask ( - id integer identity, - name varchar(40), - description varchar(256), - url varchar(80), - UNIQUE (name) -); - -\p Creating table pctasklist -CREATE TABLE pctasklist ( - id integer identity, - host varchar(20) not null, - tasksequence int not null, - pctask integer, - assigndate timestamp default current_timestamp, - completedate timestamp, - show boolean default true, - FOREIGN KEY (pctask) REFERENCES pctask, - UNIQUE (host, tasksequence) -); - -\p Granting privileges -GRANT select ON pctask TO public; -GRANT all ON pctask TO tomcat; -GRANT select ON pctasklist TO public; -GRANT all ON pctasklist TO tomcat; - -\p Inserting test records -INSERT INTO pctask (name, description, url) VALUES ( - 'task one', 'Description for task 1', 'http://cnn.com'); -INSERT INTO pctasklist (host, tasksequence, pctask) VALUES ( - 'admc-masq', 101, (SELECT id FROM pctask WHERE name = 'task one')); - -commit; diff --git a/database/hsqldb/sample/sampledata.sql b/database/hsqldb/sample/sampledata.sql deleted file mode 100644 index 833d143f..00000000 --- a/database/hsqldb/sample/sampledata.sql +++ /dev/null @@ -1,822 +0,0 @@ -/* - * $Id: sampledata.sql 3348 2009-12-15 14:24:19Z unsaved $ - * - * Creates and populates database objects with sample data. - * This file was created by grabbing the commands made by creating - * sample data with the DatabaseManager utility. - */ - - -DROP TABLE Item IF EXISTS; -DROP TABLE Invoice IF EXISTS; -DROP TABLE Product IF EXISTS; -DROP TABLE Customer IF EXISTS; -CREATE TABLE Customer(ID INTEGER PRIMARY KEY,FirstName VARCHAR(20),LastName VARCHAR(30),Street VARCHAR(50),City VARCHAR(25)); -CREATE TABLE Product(ID INTEGER PRIMARY KEY,Name VARCHAR(30),Price DECIMAL); -CREATE TABLE Invoice(ID INTEGER PRIMARY KEY,CustomerID INTEGER,Total DECIMAL, FOREIGN KEY (CustomerId) REFERENCES Customer(ID) ON DELETE CASCADE); -CREATE TABLE Item(InvoiceID INTEGER,Item INTEGER,ProductID INTEGER,Quantity INTEGER,Cost DECIMAL,PRIMARY KEY(InvoiceID,Item), FOREIGN KEY (InvoiceId) REFERENCES Invoice (ID) ON DELETE CASCADE, FOREIGN KEY (ProductId) REFERENCES Product(ID) ON DELETE CASCADE); -INSERT INTO Customer VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas'); -INSERT INTO Product VALUES(0,'Iron Iron',54); -INSERT INTO Customer VALUES(1,'Susanne','King','366 - 20th Ave.','Olten'); -INSERT INTO Product VALUES(1,'Chair Shoe',248); -INSERT INTO Customer VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon'); -INSERT INTO Product VALUES(2,'Telephone Clock',248); -INSERT INTO Customer VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco'); -INSERT INTO Product VALUES(3,'Chair Chair',254); -INSERT INTO Customer VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas'); -INSERT INTO Product VALUES(4,'Ice Tea Shoe',128); -INSERT INTO Customer VALUES(5,'Laura','Miller','294 Seventh Av.','Paris'); -INSERT INTO Product VALUES(5,'Clock Clock',236); -INSERT INTO Customer VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto'); -INSERT INTO Product VALUES(6,'Ice Tea Chair',98); -INSERT INTO Customer VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco'); -INSERT INTO Product VALUES(7,'Telephone Shoe',84); -INSERT INTO Customer VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle'); -INSERT INTO Product VALUES(8,'Ice Tea Clock',226); -INSERT INTO Customer VALUES(9,'James','Schneider','277 Seventh Av.','Berne'); -INSERT INTO Product VALUES(9,'Clock Telephone',172); -INSERT INTO Customer VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas'); -INSERT INTO Product VALUES(10,'Telephone Ice Tea',204); -INSERT INTO Customer VALUES(11,'Julia','White','412 Upland Pl.','Chicago'); -INSERT INTO Product VALUES(11,'Telephone Iron',88); -INSERT INTO Customer VALUES(12,'George','Ott','381 Upland Pl.','Palo Alto'); -INSERT INTO Product VALUES(12,'Clock Ice Tea',168); -INSERT INTO Customer VALUES(13,'Laura','Ringer','38 College Av.','New York'); -INSERT INTO Product VALUES(13,'Telephone Clock',180); -INSERT INTO Customer VALUES(14,'Bill','Karsen','53 College Av.','Oslo'); -INSERT INTO Product VALUES(14,'Telephone Iron',124); -INSERT INTO Customer VALUES(15,'Bill','Clancy','319 Upland Pl.','Seattle'); -INSERT INTO Product VALUES(15,'Ice Tea Chair',94); -INSERT INTO Customer VALUES(16,'John','Fuller','195 Seventh Av.','New York'); -INSERT INTO Product VALUES(16,'Ice Tea Shoe',194); -INSERT INTO Customer VALUES(17,'Laura','Ott','443 Seventh Av.','Lyon'); -INSERT INTO Product VALUES(17,'Clock Ice Tea',220); -INSERT INTO Customer VALUES(18,'Sylvia','Fuller','158 - 20th Ave.','Paris'); -INSERT INTO Product VALUES(18,'Chair Clock',172); -INSERT INTO Customer VALUES(19,'Susanne','Heiniger','86 - 20th Ave.','Dallas'); -INSERT INTO Product VALUES(19,'Ice Tea Ice Tea',110); -INSERT INTO Customer VALUES(20,'Janet','Schneider','309 - 20th Ave.','Oslo'); -INSERT INTO Product VALUES(20,'Ice Tea Telephone',200); -INSERT INTO Customer VALUES(21,'Julia','Clancy','18 Seventh Av.','Seattle'); -INSERT INTO Product VALUES(21,'Chair Chair',114); -INSERT INTO Customer VALUES(22,'Bill','Ott','250 - 20th Ave.','Berne'); -INSERT INTO Product VALUES(22,'Iron Iron',66); -INSERT INTO Customer VALUES(23,'Julia','Heiniger','358 College Av.','Boston'); -INSERT INTO Product VALUES(23,'Shoe Chair',76); -INSERT INTO Customer VALUES(24,'James','Sommer','333 Upland Pl.','Olten'); -INSERT INTO Product VALUES(24,'Chair Shoe',72); -INSERT INTO Customer VALUES(25,'Sylvia','Steel','269 College Av.','Paris'); -INSERT INTO Product VALUES(25,'Shoe Shoe',162); -INSERT INTO Customer VALUES(26,'James','Clancy','195 Upland Pl.','Oslo'); -INSERT INTO Product VALUES(26,'Shoe Shoe',252); -INSERT INTO Customer VALUES(27,'Bob','Sommer','509 College Av.','Seattle'); -INSERT INTO Product VALUES(27,'Telephone Iron',230); -INSERT INTO Customer VALUES(28,'Susanne','White','74 - 20th Ave.','Lyon'); -INSERT INTO Product VALUES(28,'Clock Iron',30); -INSERT INTO Customer VALUES(29,'Andrew','Smith','254 College Av.','New York'); -INSERT INTO Product VALUES(29,'Chair Telephone',112); -INSERT INTO Customer VALUES(30,'Bill','Sommer','362 - 20th Ave.','Olten'); -INSERT INTO Product VALUES(30,'Shoe Iron',232); -INSERT INTO Customer VALUES(31,'Bob','Ringer','371 College Av.','Olten'); -INSERT INTO Product VALUES(31,'Ice Tea Telephone',48); -INSERT INTO Customer VALUES(32,'Michael','Ott','339 College Av.','Boston'); -INSERT INTO Product VALUES(32,'Clock Iron',190); -INSERT INTO Customer VALUES(33,'Mary','King','491 College Av.','Oslo'); -INSERT INTO Product VALUES(33,'Iron Chair',182); -INSERT INTO Customer VALUES(34,'Julia','May','33 Upland Pl.','Seattle'); -INSERT INTO Product VALUES(34,'Chair Iron',256); -INSERT INTO Customer VALUES(35,'George','Karsen','412 College Av.','Chicago'); -INSERT INTO Product VALUES(35,'Telephone Shoe',76); -INSERT INTO Customer VALUES(36,'John','Steel','276 Upland Pl.','Dallas'); -INSERT INTO Product VALUES(36,'Ice Tea Iron',32); -INSERT INTO Customer VALUES(37,'Michael','Clancy','19 Seventh Av.','Dallas'); -INSERT INTO Product VALUES(37,'Clock Shoe',94); -INSERT INTO Customer VALUES(38,'Andrew','Heiniger','347 College Av.','Lyon'); -INSERT INTO Product VALUES(38,'Clock Ice Tea',216); -INSERT INTO Customer VALUES(39,'Mary','Karsen','202 College Av.','Chicago'); -INSERT INTO Product VALUES(39,'Ice Tea Shoe',154); -INSERT INTO Customer VALUES(40,'Susanne','Miller','440 - 20th Ave.','Dallas'); -INSERT INTO Product VALUES(40,'Shoe Clock',28); -INSERT INTO Customer VALUES(41,'Bill','King','546 College Av.','New York'); -INSERT INTO Product VALUES(41,'Clock Ice Tea',206); -INSERT INTO Customer VALUES(42,'Robert','Ott','503 Seventh Av.','Oslo'); -INSERT INTO Product VALUES(42,'Iron Chair',198); -INSERT INTO Customer VALUES(43,'Susanne','Smith','2 Upland Pl.','Dallas'); -INSERT INTO Product VALUES(43,'Telephone Clock',94); -INSERT INTO Customer VALUES(44,'Sylvia','Ott','361 College Av.','New York'); -INSERT INTO Product VALUES(44,'Ice Tea Ice Tea',96); -INSERT INTO Customer VALUES(45,'Janet','May','396 Seventh Av.','Oslo'); -INSERT INTO Product VALUES(45,'Iron Ice Tea',180); -INSERT INTO Customer VALUES(46,'Andrew','May','172 Seventh Av.','New York'); -INSERT INTO Product VALUES(46,'Ice Tea Clock',62); -INSERT INTO Customer VALUES(47,'Janet','Fuller','445 Upland Pl.','Dallas'); -INSERT INTO Product VALUES(47,'Ice Tea Iron',178); -INSERT INTO Customer VALUES(48,'Robert','White','549 Seventh Av.','San Francisco'); -INSERT INTO Product VALUES(48,'Clock Clock',210); -INSERT INTO Customer VALUES(49,'George','Fuller','534 - 20th Ave.','Olten'); -INSERT INTO Product VALUES(49,'Iron Iron',22); -INSERT INTO Invoice VALUES(0,0,0.0); -INSERT INTO Invoice VALUES(1,33,0.0); -INSERT INTO Invoice VALUES(2,23,0.0); -INSERT INTO Invoice VALUES(3,21,0.0); -INSERT INTO Invoice VALUES(4,30,0.0); -INSERT INTO Invoice VALUES(5,34,0.0); -INSERT INTO Invoice VALUES(6,19,0.0); -INSERT INTO Invoice VALUES(7,26,0.0); -INSERT INTO Invoice VALUES(8,29,0.0); -INSERT INTO Invoice VALUES(9,38,0.0); -INSERT INTO Invoice VALUES(10,24,0.0); -INSERT INTO Invoice VALUES(11,24,0.0); -INSERT INTO Invoice VALUES(12,23,0.0); -INSERT INTO Invoice VALUES(13,39,0.0); -INSERT INTO Invoice VALUES(14,35,0.0); -INSERT INTO Invoice VALUES(15,39,0.0); -INSERT INTO Invoice VALUES(16,45,0.0); -INSERT INTO Invoice VALUES(17,46,0.0); -INSERT INTO Invoice VALUES(18,4,0.0); -INSERT INTO Invoice VALUES(19,9,0.0); -INSERT INTO Invoice VALUES(20,19,0.0); -INSERT INTO Invoice VALUES(21,8,0.0); -INSERT INTO Invoice VALUES(22,40,0.0); -INSERT INTO Invoice VALUES(23,36,0.0); -INSERT INTO Invoice VALUES(24,15,0.0); -INSERT INTO Invoice VALUES(25,31,0.0); -INSERT INTO Invoice VALUES(26,27,0.0); -INSERT INTO Invoice VALUES(27,24,0.0); -INSERT INTO Invoice VALUES(28,35,0.0); -INSERT INTO Invoice VALUES(29,46,0.0); -INSERT INTO Invoice VALUES(30,13,0.0); -INSERT INTO Invoice VALUES(31,22,0.0); -INSERT INTO Invoice VALUES(32,20,0.0); -INSERT INTO Invoice VALUES(33,40,0.0); -INSERT INTO Invoice VALUES(34,33,0.0); -INSERT INTO Invoice VALUES(35,4,0.0); -INSERT INTO Invoice VALUES(36,42,0.0); -INSERT INTO Invoice VALUES(37,39,0.0); -INSERT INTO Invoice VALUES(38,46,0.0); -INSERT INTO Invoice VALUES(39,5,0.0); -INSERT INTO Invoice VALUES(40,4,0.0); -INSERT INTO Invoice VALUES(41,19,0.0); -INSERT INTO Invoice VALUES(42,38,0.0); -INSERT INTO Invoice VALUES(43,13,0.0); -INSERT INTO Invoice VALUES(44,32,0.0); -INSERT INTO Invoice VALUES(45,42,0.0); -INSERT INTO Invoice VALUES(46,24,0.0); -INSERT INTO Invoice VALUES(47,45,0.0); -INSERT INTO Invoice VALUES(48,22,0.0); -INSERT INTO Invoice VALUES(49,32,0.0); -INSERT INTO Item VALUES(0,12,1,11,1.5); -INSERT INTO Item VALUES(0,11,12,4,1.5); -INSERT INTO Item VALUES(0,10,4,8,1.5); -INSERT INTO Item VALUES(0,9,35,4,1.5); -INSERT INTO Item VALUES(0,8,0,23,1.5); -INSERT INTO Item VALUES(0,7,7,10,1.5); -INSERT INTO Item VALUES(0,6,16,9,1.5); -INSERT INTO Item VALUES(0,5,12,15,1.5); -INSERT INTO Item VALUES(0,4,47,1,1.5); -INSERT INTO Item VALUES(0,3,1,9,1.5); -INSERT INTO Item VALUES(0,2,47,3,1.5); -INSERT INTO Item VALUES(0,1,14,19,1.5); -INSERT INTO Item VALUES(0,0,7,12,1.5); -INSERT INTO Item VALUES(1,6,25,19,1.5); -INSERT INTO Item VALUES(1,5,25,9,1.5); -INSERT INTO Item VALUES(1,4,16,16,1.5); -INSERT INTO Item VALUES(1,3,38,8,1.5); -INSERT INTO Item VALUES(1,2,19,6,1.5); -INSERT INTO Item VALUES(1,1,0,9,1.5); -INSERT INTO Item VALUES(1,0,40,8,1.5); -INSERT INTO Item VALUES(2,16,36,24,1.5); -INSERT INTO Item VALUES(2,15,0,18,1.5); -INSERT INTO Item VALUES(2,14,48,19,1.5); -INSERT INTO Item VALUES(2,13,12,1,1.5); -INSERT INTO Item VALUES(2,12,21,15,1.5); -INSERT INTO Item VALUES(2,11,42,21,1.5); -INSERT INTO Item VALUES(2,10,49,11,1.5); -INSERT INTO Item VALUES(2,9,18,7,1.5); -INSERT INTO Item VALUES(2,8,39,2,1.5); -INSERT INTO Item VALUES(2,7,30,5,1.5); -INSERT INTO Item VALUES(2,6,43,8,1.5); -INSERT INTO Item VALUES(2,5,30,4,1.5); -INSERT INTO Item VALUES(2,4,38,18,1.5); -INSERT INTO Item VALUES(2,3,19,13,1.5); -INSERT INTO Item VALUES(2,2,11,9,1.5); -INSERT INTO Item VALUES(2,1,25,3,1.5); -INSERT INTO Item VALUES(2,0,4,18,1.5); -INSERT INTO Item VALUES(3,17,30,17,1.5); -INSERT INTO Item VALUES(3,16,19,11,1.5); -INSERT INTO Item VALUES(3,15,23,18,1.5); -INSERT INTO Item VALUES(3,14,17,22,1.5); -INSERT INTO Item VALUES(3,13,41,2,1.5); -INSERT INTO Item VALUES(3,12,41,22,1.5); -INSERT INTO Item VALUES(3,11,7,11,1.5); -INSERT INTO Item VALUES(3,10,10,17,1.5); -INSERT INTO Item VALUES(3,9,29,17,1.5); -INSERT INTO Item VALUES(3,8,49,9,1.5); -INSERT INTO Item VALUES(3,7,26,4,1.5); -INSERT INTO Item VALUES(3,6,13,18,1.5); -INSERT INTO Item VALUES(3,5,30,10,1.5); -INSERT INTO Item VALUES(3,4,20,12,1.5); -INSERT INTO Item VALUES(3,3,0,22,1.5); -INSERT INTO Item VALUES(3,2,49,3,1.5); -INSERT INTO Item VALUES(3,1,1,20,1.5); -INSERT INTO Item VALUES(3,0,11,21,1.5); -INSERT INTO Item VALUES(4,5,37,24,1.5); -INSERT INTO Item VALUES(4,4,9,18,1.5); -INSERT INTO Item VALUES(4,3,23,20,1.5); -INSERT INTO Item VALUES(4,2,41,23,1.5); -INSERT INTO Item VALUES(4,1,35,15,1.5); -INSERT INTO Item VALUES(4,0,28,9,1.5); -INSERT INTO Item VALUES(5,13,18,17,1.5); -INSERT INTO Item VALUES(5,12,8,15,1.5); -INSERT INTO Item VALUES(5,11,38,23,1.5); -INSERT INTO Item VALUES(5,10,28,18,1.5); -INSERT INTO Item VALUES(5,9,37,9,1.5); -INSERT INTO Item VALUES(5,8,20,3,1.5); -INSERT INTO Item VALUES(5,7,2,4,1.5); -INSERT INTO Item VALUES(5,6,7,9,1.5); -INSERT INTO Item VALUES(5,5,46,15,1.5); -INSERT INTO Item VALUES(5,4,32,14,1.5); -INSERT INTO Item VALUES(5,3,24,12,1.5); -INSERT INTO Item VALUES(5,2,20,18,1.5); -INSERT INTO Item VALUES(5,1,9,23,1.5); -INSERT INTO Item VALUES(5,0,9,5,1.5); -INSERT INTO Item VALUES(6,11,44,1,1.5); -INSERT INTO Item VALUES(6,10,16,13,1.5); -INSERT INTO Item VALUES(6,9,19,2,1.5); -INSERT INTO Item VALUES(6,8,41,19,1.5); -INSERT INTO Item VALUES(6,7,26,10,1.5); -INSERT INTO Item VALUES(6,6,37,22,1.5); -INSERT INTO Item VALUES(6,5,14,20,1.5); -INSERT INTO Item VALUES(6,4,31,20,1.5); -INSERT INTO Item VALUES(6,3,30,2,1.5); -INSERT INTO Item VALUES(6,2,23,8,1.5); -INSERT INTO Item VALUES(6,1,38,21,1.5); -INSERT INTO Item VALUES(6,0,15,20,1.5); -INSERT INTO Item VALUES(7,18,23,5,1.5); -INSERT INTO Item VALUES(7,17,40,1,1.5); -INSERT INTO Item VALUES(7,16,7,12,1.5); -INSERT INTO Item VALUES(7,15,24,17,1.5); -INSERT INTO Item VALUES(7,14,47,14,1.5); -INSERT INTO Item VALUES(7,13,32,23,1.5); -INSERT INTO Item VALUES(7,12,40,16,1.5); -INSERT INTO Item VALUES(7,11,19,13,1.5); -INSERT INTO Item VALUES(7,10,7,1,1.5); -INSERT INTO Item VALUES(7,9,9,21,1.5); -INSERT INTO Item VALUES(7,8,42,19,1.5); -INSERT INTO Item VALUES(7,7,2,22,1.5); -INSERT INTO Item VALUES(7,6,14,4,1.5); -INSERT INTO Item VALUES(7,5,24,10,1.5); -INSERT INTO Item VALUES(7,4,2,13,1.5); -INSERT INTO Item VALUES(7,3,30,2,1.5); -INSERT INTO Item VALUES(7,2,27,17,1.5); -INSERT INTO Item VALUES(7,1,23,12,1.5); -INSERT INTO Item VALUES(7,0,43,16,1.5); -INSERT INTO Item VALUES(8,9,21,23,1.5); -INSERT INTO Item VALUES(8,8,38,7,1.5); -INSERT INTO Item VALUES(8,7,6,5,1.5); -INSERT INTO Item VALUES(8,6,15,19,1.5); -INSERT INTO Item VALUES(8,5,24,18,1.5); -INSERT INTO Item VALUES(8,4,15,8,1.5); -INSERT INTO Item VALUES(8,3,41,16,1.5); -INSERT INTO Item VALUES(8,2,11,8,1.5); -INSERT INTO Item VALUES(8,1,44,16,1.5); -INSERT INTO Item VALUES(8,0,34,15,1.5); -INSERT INTO Item VALUES(9,19,48,23,1.5); -INSERT INTO Item VALUES(9,18,3,12,1.5); -INSERT INTO Item VALUES(9,17,13,17,1.5); -INSERT INTO Item VALUES(9,16,24,10,1.5); -INSERT INTO Item VALUES(9,15,48,23,1.5); -INSERT INTO Item VALUES(9,14,15,8,1.5); -INSERT INTO Item VALUES(9,13,42,13,1.5); -INSERT INTO Item VALUES(9,12,25,23,1.5); -INSERT INTO Item VALUES(9,11,12,16,1.5); -INSERT INTO Item VALUES(9,10,38,11,1.5); -INSERT INTO Item VALUES(9,9,13,6,1.5); -INSERT INTO Item VALUES(9,8,24,11,1.5); -INSERT INTO Item VALUES(9,7,2,22,1.5); -INSERT INTO Item VALUES(9,6,18,10,1.5); -INSERT INTO Item VALUES(9,5,6,2,1.5); -INSERT INTO Item VALUES(9,4,36,16,1.5); -INSERT INTO Item VALUES(9,3,4,14,1.5); -INSERT INTO Item VALUES(9,2,29,12,1.5); -INSERT INTO Item VALUES(9,1,18,21,1.5); -INSERT INTO Item VALUES(9,0,45,8,1.5); -INSERT INTO Item VALUES(10,9,5,10,1.5); -INSERT INTO Item VALUES(10,8,22,11,1.5); -INSERT INTO Item VALUES(10,7,4,13,1.5); -INSERT INTO Item VALUES(10,6,18,14,1.5); -INSERT INTO Item VALUES(10,5,5,24,1.5); -INSERT INTO Item VALUES(10,4,10,24,1.5); -INSERT INTO Item VALUES(10,3,46,1,1.5); -INSERT INTO Item VALUES(10,2,7,9,1.5); -INSERT INTO Item VALUES(10,1,33,17,1.5); -INSERT INTO Item VALUES(10,0,20,1,1.5); -INSERT INTO Item VALUES(11,8,20,1,1.5); -INSERT INTO Item VALUES(11,7,48,22,1.5); -INSERT INTO Item VALUES(11,6,0,12,1.5); -INSERT INTO Item VALUES(11,5,19,2,1.5); -INSERT INTO Item VALUES(11,4,47,16,1.5); -INSERT INTO Item VALUES(11,3,32,21,1.5); -INSERT INTO Item VALUES(11,2,0,3,1.5); -INSERT INTO Item VALUES(11,1,21,21,1.5); -INSERT INTO Item VALUES(11,0,45,10,1.5); -INSERT INTO Item VALUES(12,18,9,4,1.5); -INSERT INTO Item VALUES(12,17,31,15,1.5); -INSERT INTO Item VALUES(12,16,0,9,1.5); -INSERT INTO Item VALUES(12,15,22,16,1.5); -INSERT INTO Item VALUES(12,14,25,11,1.5); -INSERT INTO Item VALUES(12,13,36,21,1.5); -INSERT INTO Item VALUES(12,12,13,12,1.5); -INSERT INTO Item VALUES(12,11,28,16,1.5); -INSERT INTO Item VALUES(12,10,46,19,1.5); -INSERT INTO Item VALUES(12,9,25,22,1.5); -INSERT INTO Item VALUES(12,8,48,2,1.5); -INSERT INTO Item VALUES(12,7,48,7,1.5); -INSERT INTO Item VALUES(12,6,31,15,1.5); -INSERT INTO Item VALUES(12,5,37,17,1.5); -INSERT INTO Item VALUES(12,4,20,11,1.5); -INSERT INTO Item VALUES(12,3,0,18,1.5); -INSERT INTO Item VALUES(12,2,6,5,1.5); -INSERT INTO Item VALUES(12,1,41,19,1.5); -INSERT INTO Item VALUES(12,0,1,24,1.5); -INSERT INTO Item VALUES(13,21,40,1,1.5); -INSERT INTO Item VALUES(13,20,5,19,1.5); -INSERT INTO Item VALUES(13,19,42,18,1.5); -INSERT INTO Item VALUES(13,18,0,16,1.5); -INSERT INTO Item VALUES(13,17,32,18,1.5); -INSERT INTO Item VALUES(13,16,22,23,1.5); -INSERT INTO Item VALUES(13,15,0,20,1.5); -INSERT INTO Item VALUES(13,14,1,12,1.5); -INSERT INTO Item VALUES(13,13,10,20,1.5); -INSERT INTO Item VALUES(13,12,17,3,1.5); -INSERT INTO Item VALUES(13,11,14,3,1.5); -INSERT INTO Item VALUES(13,10,45,24,1.5); -INSERT INTO Item VALUES(13,9,24,10,1.5); -INSERT INTO Item VALUES(13,8,48,11,1.5); -INSERT INTO Item VALUES(13,7,29,24,1.5); -INSERT INTO Item VALUES(13,6,19,8,1.5); -INSERT INTO Item VALUES(13,5,22,19,1.5); -INSERT INTO Item VALUES(13,4,26,21,1.5); -INSERT INTO Item VALUES(13,3,32,2,1.5); -INSERT INTO Item VALUES(13,2,13,20,1.5); -INSERT INTO Item VALUES(13,1,1,1,1.5); -INSERT INTO Item VALUES(13,0,16,10,1.5); -INSERT INTO Item VALUES(14,13,11,23,1.5); -INSERT INTO Item VALUES(14,12,4,20,1.5); -INSERT INTO Item VALUES(14,11,25,15,1.5); -INSERT INTO Item VALUES(14,10,44,16,1.5); -INSERT INTO Item VALUES(14,9,13,16,1.5); -INSERT INTO Item VALUES(14,8,23,7,1.5); -INSERT INTO Item VALUES(14,7,43,4,1.5); -INSERT INTO Item VALUES(14,6,26,18,1.5); -INSERT INTO Item VALUES(14,5,11,8,1.5); -INSERT INTO Item VALUES(14,4,41,17,1.5); -INSERT INTO Item VALUES(14,3,34,11,1.5); -INSERT INTO Item VALUES(14,2,15,18,1.5); -INSERT INTO Item VALUES(14,1,9,22,1.5); -INSERT INTO Item VALUES(14,0,42,18,1.5); -INSERT INTO Item VALUES(15,2,24,6,1.5); -INSERT INTO Item VALUES(15,1,13,21,1.5); -INSERT INTO Item VALUES(15,0,17,12,1.5); -INSERT INTO Item VALUES(16,15,12,3,1.5); -INSERT INTO Item VALUES(16,14,0,19,1.5); -INSERT INTO Item VALUES(16,13,20,1,1.5); -INSERT INTO Item VALUES(16,12,18,2,1.5); -INSERT INTO Item VALUES(16,11,24,7,1.5); -INSERT INTO Item VALUES(16,10,43,8,1.5); -INSERT INTO Item VALUES(16,9,11,10,1.5); -INSERT INTO Item VALUES(16,8,13,17,1.5); -INSERT INTO Item VALUES(16,7,8,17,1.5); -INSERT INTO Item VALUES(16,6,44,7,1.5); -INSERT INTO Item VALUES(16,5,11,15,1.5); -INSERT INTO Item VALUES(16,4,10,24,1.5); -INSERT INTO Item VALUES(16,3,0,3,1.5); -INSERT INTO Item VALUES(16,2,20,15,1.5); -INSERT INTO Item VALUES(16,1,36,20,1.5); -INSERT INTO Item VALUES(16,0,18,15,1.5); -INSERT INTO Item VALUES(17,19,46,12,1.5); -INSERT INTO Item VALUES(17,18,5,9,1.5); -INSERT INTO Item VALUES(17,17,7,5,1.5); -INSERT INTO Item VALUES(17,16,8,16,1.5); -INSERT INTO Item VALUES(17,15,35,10,1.5); -INSERT INTO Item VALUES(17,14,18,2,1.5); -INSERT INTO Item VALUES(17,13,41,5,1.5); -INSERT INTO Item VALUES(17,12,22,16,1.5); -INSERT INTO Item VALUES(17,11,45,10,1.5); -INSERT INTO Item VALUES(17,10,10,12,1.5); -INSERT INTO Item VALUES(17,9,8,15,1.5); -INSERT INTO Item VALUES(17,8,49,8,1.5); -INSERT INTO Item VALUES(17,7,6,15,1.5); -INSERT INTO Item VALUES(17,6,43,6,1.5); -INSERT INTO Item VALUES(17,5,44,1,1.5); -INSERT INTO Item VALUES(17,4,23,2,1.5); -INSERT INTO Item VALUES(17,3,24,4,1.5); -INSERT INTO Item VALUES(17,2,44,11,1.5); -INSERT INTO Item VALUES(17,1,19,19,1.5); -INSERT INTO Item VALUES(17,0,16,8,1.5); -INSERT INTO Item VALUES(18,18,10,1,1.5); -INSERT INTO Item VALUES(18,17,8,1,1.5); -INSERT INTO Item VALUES(18,16,31,12,1.5); -INSERT INTO Item VALUES(18,15,44,20,1.5); -INSERT INTO Item VALUES(18,14,28,20,1.5); -INSERT INTO Item VALUES(18,13,14,12,1.5); -INSERT INTO Item VALUES(18,12,37,12,1.5); -INSERT INTO Item VALUES(18,11,30,8,1.5); -INSERT INTO Item VALUES(18,10,34,18,1.5); -INSERT INTO Item VALUES(18,9,2,2,1.5); -INSERT INTO Item VALUES(18,8,1,24,1.5); -INSERT INTO Item VALUES(18,7,15,14,1.5); -INSERT INTO Item VALUES(18,6,29,4,1.5); -INSERT INTO Item VALUES(18,5,15,6,1.5); -INSERT INTO Item VALUES(18,4,28,6,1.5); -INSERT INTO Item VALUES(18,3,19,8,1.5); -INSERT INTO Item VALUES(18,2,40,12,1.5); -INSERT INTO Item VALUES(18,1,33,12,1.5); -INSERT INTO Item VALUES(18,0,32,1,1.5); -INSERT INTO Item VALUES(19,4,36,24,1.5); -INSERT INTO Item VALUES(19,3,49,23,1.5); -INSERT INTO Item VALUES(19,2,4,22,1.5); -INSERT INTO Item VALUES(19,1,31,2,1.5); -INSERT INTO Item VALUES(19,0,12,7,1.5); -INSERT INTO Item VALUES(20,11,15,8,1.5); -INSERT INTO Item VALUES(20,10,25,11,1.5); -INSERT INTO Item VALUES(20,9,12,8,1.5); -INSERT INTO Item VALUES(20,8,44,18,1.5); -INSERT INTO Item VALUES(20,7,9,9,1.5); -INSERT INTO Item VALUES(20,6,20,2,1.5); -INSERT INTO Item VALUES(20,5,8,14,1.5); -INSERT INTO Item VALUES(20,4,30,13,1.5); -INSERT INTO Item VALUES(20,3,25,14,1.5); -INSERT INTO Item VALUES(20,2,24,22,1.5); -INSERT INTO Item VALUES(20,1,29,6,1.5); -INSERT INTO Item VALUES(20,0,47,15,1.5); -INSERT INTO Item VALUES(21,11,20,11,1.5); -INSERT INTO Item VALUES(21,10,19,14,1.5); -INSERT INTO Item VALUES(21,9,35,17,1.5); -INSERT INTO Item VALUES(21,8,44,19,1.5); -INSERT INTO Item VALUES(21,7,8,9,1.5); -INSERT INTO Item VALUES(21,6,26,7,1.5); -INSERT INTO Item VALUES(21,5,27,18,1.5); -INSERT INTO Item VALUES(21,4,49,22,1.5); -INSERT INTO Item VALUES(21,3,30,13,1.5); -INSERT INTO Item VALUES(21,2,31,17,1.5); -INSERT INTO Item VALUES(21,1,38,19,1.5); -INSERT INTO Item VALUES(21,0,9,10,1.5); -INSERT INTO Item VALUES(22,9,23,1,1.5); -INSERT INTO Item VALUES(22,8,3,2,1.5); -INSERT INTO Item VALUES(22,7,21,6,1.5); -INSERT INTO Item VALUES(22,6,4,11,1.5); -INSERT INTO Item VALUES(22,5,24,5,1.5); -INSERT INTO Item VALUES(22,4,5,21,1.5); -INSERT INTO Item VALUES(22,3,22,5,1.5); -INSERT INTO Item VALUES(22,2,12,20,1.5); -INSERT INTO Item VALUES(22,1,30,11,1.5); -INSERT INTO Item VALUES(22,0,9,6,1.5); -INSERT INTO Item VALUES(23,16,8,11,1.5); -INSERT INTO Item VALUES(23,15,13,17,1.5); -INSERT INTO Item VALUES(23,14,44,2,1.5); -INSERT INTO Item VALUES(23,13,14,17,1.5); -INSERT INTO Item VALUES(23,12,4,17,1.5); -INSERT INTO Item VALUES(23,11,41,8,1.5); -INSERT INTO Item VALUES(23,10,4,18,1.5); -INSERT INTO Item VALUES(23,9,20,18,1.5); -INSERT INTO Item VALUES(23,8,6,17,1.5); -INSERT INTO Item VALUES(23,7,39,3,1.5); -INSERT INTO Item VALUES(23,6,16,1,1.5); -INSERT INTO Item VALUES(23,5,32,14,1.5); -INSERT INTO Item VALUES(23,4,23,19,1.5); -INSERT INTO Item VALUES(23,3,40,19,1.5); -INSERT INTO Item VALUES(23,2,33,18,1.5); -INSERT INTO Item VALUES(23,1,26,8,1.5); -INSERT INTO Item VALUES(23,0,48,22,1.5); -INSERT INTO Item VALUES(24,15,39,17,1.5); -INSERT INTO Item VALUES(24,14,1,13,1.5); -INSERT INTO Item VALUES(24,13,15,21,1.5); -INSERT INTO Item VALUES(24,12,0,8,1.5); -INSERT INTO Item VALUES(24,11,1,4,1.5); -INSERT INTO Item VALUES(24,10,27,4,1.5); -INSERT INTO Item VALUES(24,9,21,8,1.5); -INSERT INTO Item VALUES(24,8,5,18,1.5); -INSERT INTO Item VALUES(24,7,7,13,1.5); -INSERT INTO Item VALUES(24,6,40,3,1.5); -INSERT INTO Item VALUES(24,5,35,16,1.5); -INSERT INTO Item VALUES(24,4,15,17,1.5); -INSERT INTO Item VALUES(24,3,17,23,1.5); -INSERT INTO Item VALUES(24,2,38,10,1.5); -INSERT INTO Item VALUES(24,1,46,18,1.5); -INSERT INTO Item VALUES(24,0,43,14,1.5); -INSERT INTO Item VALUES(25,8,38,3,1.5); -INSERT INTO Item VALUES(25,7,16,8,1.5); -INSERT INTO Item VALUES(25,6,21,18,1.5); -INSERT INTO Item VALUES(25,5,10,5,1.5); -INSERT INTO Item VALUES(25,4,47,10,1.5); -INSERT INTO Item VALUES(25,3,19,4,1.5); -INSERT INTO Item VALUES(25,2,13,8,1.5); -INSERT INTO Item VALUES(25,1,43,13,1.5); -INSERT INTO Item VALUES(25,0,5,15,1.5); -INSERT INTO Item VALUES(26,16,30,4,1.5); -INSERT INTO Item VALUES(26,15,8,6,1.5); -INSERT INTO Item VALUES(26,14,26,6,1.5); -INSERT INTO Item VALUES(26,13,13,10,1.5); -INSERT INTO Item VALUES(26,12,27,20,1.5); -INSERT INTO Item VALUES(26,11,18,3,1.5); -INSERT INTO Item VALUES(26,10,34,16,1.5); -INSERT INTO Item VALUES(26,9,1,23,1.5); -INSERT INTO Item VALUES(26,8,40,13,1.5); -INSERT INTO Item VALUES(26,7,4,16,1.5); -INSERT INTO Item VALUES(26,6,7,23,1.5); -INSERT INTO Item VALUES(26,5,38,4,1.5); -INSERT INTO Item VALUES(26,4,46,7,1.5); -INSERT INTO Item VALUES(26,3,16,3,1.5); -INSERT INTO Item VALUES(26,2,33,7,1.5); -INSERT INTO Item VALUES(26,1,43,21,1.5); -INSERT INTO Item VALUES(26,0,42,16,1.5); -INSERT INTO Item VALUES(27,2,19,1,1.5); -INSERT INTO Item VALUES(27,1,45,15,1.5); -INSERT INTO Item VALUES(27,0,24,15,1.5); -INSERT INTO Item VALUES(28,8,28,6,1.5); -INSERT INTO Item VALUES(28,7,28,8,1.5); -INSERT INTO Item VALUES(28,6,33,16,1.5); -INSERT INTO Item VALUES(28,5,49,4,1.5); -INSERT INTO Item VALUES(28,4,45,17,1.5); -INSERT INTO Item VALUES(28,3,6,3,1.5); -INSERT INTO Item VALUES(28,2,44,22,1.5); -INSERT INTO Item VALUES(28,1,15,13,1.5); -INSERT INTO Item VALUES(28,0,35,13,1.5); -INSERT INTO Item VALUES(29,8,35,6,1.5); -INSERT INTO Item VALUES(29,7,5,1,1.5); -INSERT INTO Item VALUES(29,6,4,16,1.5); -INSERT INTO Item VALUES(29,5,31,13,1.5); -INSERT INTO Item VALUES(29,4,4,7,1.5); -INSERT INTO Item VALUES(29,3,7,21,1.5); -INSERT INTO Item VALUES(29,2,17,23,1.5); -INSERT INTO Item VALUES(29,1,38,12,1.5); -INSERT INTO Item VALUES(29,0,33,17,1.5); -INSERT INTO Item VALUES(30,6,14,23,1.5); -INSERT INTO Item VALUES(30,5,43,23,1.5); -INSERT INTO Item VALUES(30,4,34,2,1.5); -INSERT INTO Item VALUES(30,3,33,2,1.5); -INSERT INTO Item VALUES(30,2,10,18,1.5); -INSERT INTO Item VALUES(30,1,16,19,1.5); -INSERT INTO Item VALUES(30,0,14,7,1.5); -INSERT INTO Item VALUES(31,10,0,3,1.5); -INSERT INTO Item VALUES(31,9,14,15,1.5); -INSERT INTO Item VALUES(31,8,7,5,1.5); -INSERT INTO Item VALUES(31,7,38,3,1.5); -INSERT INTO Item VALUES(31,6,26,16,1.5); -INSERT INTO Item VALUES(31,5,1,4,1.5); -INSERT INTO Item VALUES(31,4,8,14,1.5); -INSERT INTO Item VALUES(31,3,12,10,1.5); -INSERT INTO Item VALUES(31,2,4,3,1.5); -INSERT INTO Item VALUES(31,1,4,23,1.5); -INSERT INTO Item VALUES(31,0,33,10,1.5); -INSERT INTO Item VALUES(32,2,1,14,1.5); -INSERT INTO Item VALUES(32,1,30,13,1.5); -INSERT INTO Item VALUES(32,0,35,11,1.5); -INSERT INTO Item VALUES(33,15,38,7,1.5); -INSERT INTO Item VALUES(33,14,44,13,1.5); -INSERT INTO Item VALUES(33,13,25,16,1.5); -INSERT INTO Item VALUES(33,12,16,23,1.5); -INSERT INTO Item VALUES(33,11,5,7,1.5); -INSERT INTO Item VALUES(33,10,24,9,1.5); -INSERT INTO Item VALUES(33,9,29,5,1.5); -INSERT INTO Item VALUES(33,8,3,15,1.5); -INSERT INTO Item VALUES(33,7,43,10,1.5); -INSERT INTO Item VALUES(33,6,17,16,1.5); -INSERT INTO Item VALUES(33,5,8,11,1.5); -INSERT INTO Item VALUES(33,4,24,1,1.5); -INSERT INTO Item VALUES(33,3,48,1,1.5); -INSERT INTO Item VALUES(33,2,36,16,1.5); -INSERT INTO Item VALUES(33,1,10,21,1.5); -INSERT INTO Item VALUES(33,0,36,5,1.5); -INSERT INTO Item VALUES(34,14,46,7,1.5); -INSERT INTO Item VALUES(34,13,30,14,1.5); -INSERT INTO Item VALUES(34,12,43,21,1.5); -INSERT INTO Item VALUES(34,11,4,17,1.5); -INSERT INTO Item VALUES(34,10,41,16,1.5); -INSERT INTO Item VALUES(34,9,8,17,1.5); -INSERT INTO Item VALUES(34,8,3,1,1.5); -INSERT INTO Item VALUES(34,7,21,22,1.5); -INSERT INTO Item VALUES(34,6,32,7,1.5); -INSERT INTO Item VALUES(34,5,45,13,1.5); -INSERT INTO Item VALUES(34,4,27,1,1.5); -INSERT INTO Item VALUES(34,3,44,15,1.5); -INSERT INTO Item VALUES(34,2,28,22,1.5); -INSERT INTO Item VALUES(34,1,4,3,1.5); -INSERT INTO Item VALUES(34,0,10,22,1.5); -INSERT INTO Item VALUES(35,13,19,17,1.5); -INSERT INTO Item VALUES(35,12,7,23,1.5); -INSERT INTO Item VALUES(35,11,44,9,1.5); -INSERT INTO Item VALUES(35,10,17,11,1.5); -INSERT INTO Item VALUES(35,9,19,1,1.5); -INSERT INTO Item VALUES(35,8,0,1,1.5); -INSERT INTO Item VALUES(35,7,22,15,1.5); -INSERT INTO Item VALUES(35,6,5,4,1.5); -INSERT INTO Item VALUES(35,5,33,5,1.5); -INSERT INTO Item VALUES(35,4,14,17,1.5); -INSERT INTO Item VALUES(35,3,27,10,1.5); -INSERT INTO Item VALUES(35,2,14,4,1.5); -INSERT INTO Item VALUES(35,1,3,9,1.5); -INSERT INTO Item VALUES(35,0,20,17,1.5); -INSERT INTO Item VALUES(36,11,44,9,1.5); -INSERT INTO Item VALUES(36,10,47,11,1.5); -INSERT INTO Item VALUES(36,9,31,18,1.5); -INSERT INTO Item VALUES(36,8,4,21,1.5); -INSERT INTO Item VALUES(36,7,39,19,1.5); -INSERT INTO Item VALUES(36,6,39,20,1.5); -INSERT INTO Item VALUES(36,5,25,8,1.5); -INSERT INTO Item VALUES(36,4,40,5,1.5); -INSERT INTO Item VALUES(36,3,10,8,1.5); -INSERT INTO Item VALUES(36,2,1,6,1.5); -INSERT INTO Item VALUES(36,1,15,23,1.5); -INSERT INTO Item VALUES(36,0,18,13,1.5); -INSERT INTO Item VALUES(37,21,6,9,1.5); -INSERT INTO Item VALUES(37,20,14,1,1.5); -INSERT INTO Item VALUES(37,19,19,20,1.5); -INSERT INTO Item VALUES(37,18,26,22,1.5); -INSERT INTO Item VALUES(37,17,38,18,1.5); -INSERT INTO Item VALUES(37,16,27,8,1.5); -INSERT INTO Item VALUES(37,15,32,12,1.5); -INSERT INTO Item VALUES(37,14,12,3,1.5); -INSERT INTO Item VALUES(37,13,32,3,1.5); -INSERT INTO Item VALUES(37,12,24,23,1.5); -INSERT INTO Item VALUES(37,11,30,5,1.5); -INSERT INTO Item VALUES(37,10,1,18,1.5); -INSERT INTO Item VALUES(37,9,47,16,1.5); -INSERT INTO Item VALUES(37,8,46,9,1.5); -INSERT INTO Item VALUES(37,7,24,19,1.5); -INSERT INTO Item VALUES(37,6,34,12,1.5); -INSERT INTO Item VALUES(37,5,1,14,1.5); -INSERT INTO Item VALUES(37,4,13,20,1.5); -INSERT INTO Item VALUES(37,3,26,7,1.5); -INSERT INTO Item VALUES(37,2,36,8,1.5); -INSERT INTO Item VALUES(37,1,15,20,1.5); -INSERT INTO Item VALUES(37,0,41,24,1.5); -INSERT INTO Item VALUES(38,19,4,7,1.5); -INSERT INTO Item VALUES(38,18,28,20,1.5); -INSERT INTO Item VALUES(38,17,32,4,1.5); -INSERT INTO Item VALUES(38,16,40,18,1.5); -INSERT INTO Item VALUES(38,15,47,10,1.5); -INSERT INTO Item VALUES(38,14,20,7,1.5); -INSERT INTO Item VALUES(38,13,8,7,1.5); -INSERT INTO Item VALUES(38,12,1,18,1.5); -INSERT INTO Item VALUES(38,11,19,18,1.5); -INSERT INTO Item VALUES(38,10,4,18,1.5); -INSERT INTO Item VALUES(38,9,27,20,1.5); -INSERT INTO Item VALUES(38,8,40,10,1.5); -INSERT INTO Item VALUES(38,7,15,1,1.5); -INSERT INTO Item VALUES(38,6,5,19,1.5); -INSERT INTO Item VALUES(38,5,48,17,1.5); -INSERT INTO Item VALUES(38,4,45,14,1.5); -INSERT INTO Item VALUES(38,3,27,19,1.5); -INSERT INTO Item VALUES(38,2,4,8,1.5); -INSERT INTO Item VALUES(38,1,45,13,1.5); -INSERT INTO Item VALUES(38,0,48,14,1.5); -INSERT INTO Item VALUES(39,3,20,17,1.5); -INSERT INTO Item VALUES(39,2,39,16,1.5); -INSERT INTO Item VALUES(39,1,24,6,1.5); -INSERT INTO Item VALUES(39,0,10,12,1.5); -INSERT INTO Item VALUES(40,20,4,16,1.5); -INSERT INTO Item VALUES(40,19,7,23,1.5); -INSERT INTO Item VALUES(40,18,33,11,1.5); -INSERT INTO Item VALUES(40,17,4,20,1.5); -INSERT INTO Item VALUES(40,16,27,16,1.5); -INSERT INTO Item VALUES(40,15,22,12,1.5); -INSERT INTO Item VALUES(40,14,4,24,1.5); -INSERT INTO Item VALUES(40,13,6,8,1.5); -INSERT INTO Item VALUES(40,12,35,13,1.5); -INSERT INTO Item VALUES(40,11,27,2,1.5); -INSERT INTO Item VALUES(40,10,6,11,1.5); -INSERT INTO Item VALUES(40,9,40,17,1.5); -INSERT INTO Item VALUES(40,8,11,4,1.5); -INSERT INTO Item VALUES(40,7,31,1,1.5); -INSERT INTO Item VALUES(40,6,28,12,1.5); -INSERT INTO Item VALUES(40,5,32,18,1.5); -INSERT INTO Item VALUES(40,4,18,13,1.5); -INSERT INTO Item VALUES(40,3,26,10,1.5); -INSERT INTO Item VALUES(40,2,4,5,1.5); -INSERT INTO Item VALUES(40,1,45,24,1.5); -INSERT INTO Item VALUES(40,0,46,24,1.5); -INSERT INTO Item VALUES(41,11,48,15,1.5); -INSERT INTO Item VALUES(41,10,24,20,1.5); -INSERT INTO Item VALUES(41,9,26,21,1.5); -INSERT INTO Item VALUES(41,8,9,22,1.5); -INSERT INTO Item VALUES(41,7,22,18,1.5); -INSERT INTO Item VALUES(41,6,17,11,1.5); -INSERT INTO Item VALUES(41,5,9,21,1.5); -INSERT INTO Item VALUES(41,4,16,22,1.5); -INSERT INTO Item VALUES(41,3,29,20,1.5); -INSERT INTO Item VALUES(41,2,36,2,1.5); -INSERT INTO Item VALUES(41,1,47,19,1.5); -INSERT INTO Item VALUES(41,0,5,24,1.5); -INSERT INTO Item VALUES(42,4,48,15,1.5); -INSERT INTO Item VALUES(42,3,40,14,1.5); -INSERT INTO Item VALUES(42,2,40,19,1.5); -INSERT INTO Item VALUES(42,1,18,21,1.5); -INSERT INTO Item VALUES(42,0,48,9,1.5); -INSERT INTO Item VALUES(43,16,38,12,1.5); -INSERT INTO Item VALUES(43,15,48,7,1.5); -INSERT INTO Item VALUES(43,14,3,18,1.5); -INSERT INTO Item VALUES(43,13,44,22,1.5); -INSERT INTO Item VALUES(43,12,40,24,1.5); -INSERT INTO Item VALUES(43,11,49,23,1.5); -INSERT INTO Item VALUES(43,10,35,1,1.5); -INSERT INTO Item VALUES(43,9,7,23,1.5); -INSERT INTO Item VALUES(43,8,44,8,1.5); -INSERT INTO Item VALUES(43,7,11,15,1.5); -INSERT INTO Item VALUES(43,6,24,1,1.5); -INSERT INTO Item VALUES(43,5,33,6,1.5); -INSERT INTO Item VALUES(43,4,32,22,1.5); -INSERT INTO Item VALUES(43,3,6,18,1.5); -INSERT INTO Item VALUES(43,2,2,15,1.5); -INSERT INTO Item VALUES(43,1,18,19,1.5); -INSERT INTO Item VALUES(43,0,15,22,1.5); -INSERT INTO Item VALUES(44,8,28,23,1.5); -INSERT INTO Item VALUES(44,7,49,17,1.5); -INSERT INTO Item VALUES(44,6,14,15,1.5); -INSERT INTO Item VALUES(44,5,41,22,1.5); -INSERT INTO Item VALUES(44,4,12,3,1.5); -INSERT INTO Item VALUES(44,3,3,14,1.5); -INSERT INTO Item VALUES(44,2,17,14,1.5); -INSERT INTO Item VALUES(44,1,34,17,1.5); -INSERT INTO Item VALUES(44,0,33,20,1.5); -INSERT INTO Item VALUES(45,14,3,16,1.5); -INSERT INTO Item VALUES(45,13,47,8,1.5); -INSERT INTO Item VALUES(45,12,32,13,1.5); -INSERT INTO Item VALUES(45,11,31,22,1.5); -INSERT INTO Item VALUES(45,10,41,24,1.5); -INSERT INTO Item VALUES(45,9,26,18,1.5); -INSERT INTO Item VALUES(45,8,9,2,1.5); -INSERT INTO Item VALUES(45,7,6,24,1.5); -INSERT INTO Item VALUES(45,6,39,5,1.5); -INSERT INTO Item VALUES(45,5,45,17,1.5); -INSERT INTO Item VALUES(45,4,3,14,1.5); -INSERT INTO Item VALUES(45,3,14,11,1.5); -INSERT INTO Item VALUES(45,2,46,8,1.5); -INSERT INTO Item VALUES(45,1,11,6,1.5); -INSERT INTO Item VALUES(45,0,44,6,1.5); -INSERT INTO Item VALUES(46,17,12,23,1.5); -INSERT INTO Item VALUES(46,16,46,21,1.5); -INSERT INTO Item VALUES(46,15,40,11,1.5); -INSERT INTO Item VALUES(46,14,24,10,1.5); -INSERT INTO Item VALUES(46,13,36,20,1.5); -INSERT INTO Item VALUES(46,12,21,24,1.5); -INSERT INTO Item VALUES(46,11,1,4,1.5); -INSERT INTO Item VALUES(46,10,11,24,1.5); -INSERT INTO Item VALUES(46,9,7,4,1.5); -INSERT INTO Item VALUES(46,8,8,22,1.5); -INSERT INTO Item VALUES(46,7,49,9,1.5); -INSERT INTO Item VALUES(46,6,41,18,1.5); -INSERT INTO Item VALUES(46,5,25,9,1.5); -INSERT INTO Item VALUES(46,4,17,5,1.5); -INSERT INTO Item VALUES(46,3,21,19,1.5); -INSERT INTO Item VALUES(46,2,30,14,1.5); -INSERT INTO Item VALUES(46,1,12,24,1.5); -INSERT INTO Item VALUES(46,0,5,21,1.5); -INSERT INTO Item VALUES(47,13,33,8,1.5); -INSERT INTO Item VALUES(47,12,12,20,1.5); -INSERT INTO Item VALUES(47,11,35,10,1.5); -INSERT INTO Item VALUES(47,10,45,2,1.5); -INSERT INTO Item VALUES(47,9,32,9,1.5); -INSERT INTO Item VALUES(47,8,16,2,1.5); -INSERT INTO Item VALUES(47,7,28,14,1.5); -INSERT INTO Item VALUES(47,6,8,10,1.5); -INSERT INTO Item VALUES(47,5,40,8,1.5); -INSERT INTO Item VALUES(47,4,15,1,1.5); -INSERT INTO Item VALUES(47,3,1,4,1.5); -INSERT INTO Item VALUES(47,2,17,6,1.5); -INSERT INTO Item VALUES(47,1,23,13,1.5); -INSERT INTO Item VALUES(47,0,23,15,1.5); -INSERT INTO Item VALUES(48,10,41,10,1.5); -INSERT INTO Item VALUES(48,9,35,17,1.5); -INSERT INTO Item VALUES(48,8,5,12,1.5); -INSERT INTO Item VALUES(48,7,30,19,1.5); -INSERT INTO Item VALUES(48,6,11,17,1.5); -INSERT INTO Item VALUES(48,5,24,16,1.5); -INSERT INTO Item VALUES(48,4,48,4,1.5); -INSERT INTO Item VALUES(48,3,10,2,1.5); -INSERT INTO Item VALUES(48,2,23,10,1.5); -INSERT INTO Item VALUES(48,1,26,23,1.5); -INSERT INTO Item VALUES(48,0,6,23,1.5); -INSERT INTO Item VALUES(49,16,24,18,1.5); -INSERT INTO Item VALUES(49,15,19,24,1.5); -INSERT INTO Item VALUES(49,14,23,5,1.5); -INSERT INTO Item VALUES(49,13,6,22,1.5); -INSERT INTO Item VALUES(49,12,21,17,1.5); -INSERT INTO Item VALUES(49,11,40,15,1.5); -INSERT INTO Item VALUES(49,10,30,16,1.5); -INSERT INTO Item VALUES(49,9,7,24,1.5); -INSERT INTO Item VALUES(49,8,48,24,1.5); -INSERT INTO Item VALUES(49,7,6,21,1.5); -INSERT INTO Item VALUES(49,6,29,15,1.5); -INSERT INTO Item VALUES(49,5,16,1,1.5); -INSERT INTO Item VALUES(49,4,47,14,1.5); -INSERT INTO Item VALUES(49,3,17,19,1.5); -INSERT INTO Item VALUES(49,2,29,6,1.5); -INSERT INTO Item VALUES(49,1,22,16,1.5); -INSERT INTO Item VALUES(49,0,18,6,1.5); -UPDATE Product SET Price=ROUND(Price*.1,2); -UPDATE Item SET Cost=Cost*(SELECT Price FROM Product prod WHERE ProductID=prod.ID); -UPDATE Invoice SET Total=SELECT SUM(Cost*Quantity) FROM Item WHERE InvoiceID=Invoice.ID; - -COMMIT; diff --git a/database/hsqldb/sample/server.properties b/database/hsqldb/sample/server.properties deleted file mode 100644 index 8726b347..00000000 --- a/database/hsqldb/sample/server.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Hsqldb Server cfg file. -# See the HyperSQL Network Listeners chapter of the HyperSQL User Guide. - -# Each server.database.X setting defines a database "catalog". -# I.e., an independent set of data. -# Each server.database.X setting corresponds exactly to the jdbc:hsqldb:* -# JDBC URL you would use if you wanted to get a direct (In-Process) -# Connection to the catalog instead of "serving" it. - -server.database.0=file:db0/db0 -# I suggest that, for every file: catalog you define, you add the -# connection property "ifexists=true" after the database instance -# is created (which happens simply by starting the Server one time). -# Just append ";ifexists=true" to the file: URL, like so: -# server.database.0=file:db0/db0;ifexists=true - -# server.dbname.0 defaults to "" (i.e. server.dbname.n for n==0), but -# the catalog definition n will be entirely ignored for n > 0 if you do not -# set server.dbname.n. I.e. dbname setting is required for n > 0, though it -# may be set to blank (e.g. "server.dbname.3=") diff --git a/database/hsqldb/sample/sqltool.rc b/database/hsqldb/sample/sqltool.rc deleted file mode 100644 index f5d2b521..00000000 --- a/database/hsqldb/sample/sqltool.rc +++ /dev/null @@ -1,234 +0,0 @@ -# $Id: sqltool.rc 6381 2021-11-18 21:45:56Z unsaved $ - -# This is a sample RC configuration file used by SqlTool, DatabaseManager, -# and any other program that uses the org.hsqldb.lib.RCData class. -# See the documentation for SqlTool for various ways to use this file. -# This is not a Java Properties file. It uses a custom format with stanzas, -# similar to .netrc files. - -# If you have the least concerns about security, then secure access to -# your RC file. - -# You can run SqlTool right now by copying this file to your home directory -# and running -# java -jar /path/to/sqltool.jar mem -# This will access the first urlid definition below in order to use a -# personal Memory-Only database. -# "url" values may, of course, contain JDBC connection properties, delimited -# with semicolons. -# As of revision 3347 of SqlFile, you can also connect to datasources defined -# here from within an SqlTool session/file with the command "\j urlid". - -# You can use Java system property values in this file like this: ${user.home} - -# Windows users are advised to use forward slashes instead of back-slashes, -# and to avoid paths containing spaces or other funny characters. (This -# recommendation applies to any Java app, not just SqlTool). - -# It is a runtime error to do a urlid lookup using RCData class and to not -# match any stanza (via urlid pattern) in this file. - -# Three features added recently. All are downward-compatible. -# 1. urlid field values in this file are now comma-separated (with optional -# whitespace before or after the commas) regular expressions. -# 2. Each individual urlid token value (per previous bullet) is a now a regular -# expression pattern that urlid lookups are compared to. N.b. patterns must -# match the entire lookup string, not just match "within" it. E.g. pattern -# of . would match lookup candidate "A" but not "AB". .+ will always match. -# 3. Though it is still an error to define the same exact urlid value more -# than once in this file, it is allowed (and useful) to have a url lookup -# match more than one urlid pattern and stanza. Assignments are applied -# sequentially, so you should generally add default settings with more -# liberal patterns, and override settings later in the file with more -# specific (or exact) patterns. - -# Since service discovery works great in all JREs for many years now, I -# have removed all 'driver' specifications here. JRE discover will -# automatically resolve the driver class based on the JDBC URL format. -# Most people use default ports, so I have removed port specification from -# examples except for Microsoft's Sql Server driver where you can't depend -# on a default port. -# In all cases, to specify a non-default port, insert colon and port number -# after the hostname or ip address in the JDBC URL, like -# jdbc:hsqldb:hsql://localhost:9977 or -# jdbc:sqlserver://hostname.admc.com:1433;databaseName=dbname - -# Amazon Aurora instances are access from JDBC exactly the same as the -# non-Aurora RDS counterpart. - -# For using any database engine other than HyperSQL, you must add the -# JDBC jar file and the SqlTool jar to your CLASSPATH then run a command like: -# java org.hsqldb.util.SqlTool... -# I.e., the "-jar" switch doesn't support modified classpath. -# (See SqlTool manual for how to do same thing using Java modules.) -# To oversimplify for non-developers, the two most common methods to set -# CLASSPATH for an executable tool like SqlTool are to either use the java -# "-cp" switch or set environmental variable CLASSPATH. -# Windows users can use graphical UI or CLI "set". Unix shell users must -# "export" in addition to assigning. -# -# All JDBC jar files used in these examples are available from Maven -# repositories. You can also get them from vendor web sites or with product -# bundles (especially database distributions). -# Most databases provide multiple variants. Most people will want a type 4 -# driver supporting your connection mechanism (most commonly TCP/IP service, -# but also database file access and others) and your client JRE version. -# By convention the variants are distinguished in segments of the jar file -# name before the final ".jar" . - - -# Global default. .+ matches all lookups: -urlid .+ -username SA -password - -# A personal Memory-Only (non-persistent) database. -# Inherits username and password from default setting above. -urlid mem -url jdbc:hsqldb:mem:memdbid - -# A personal, local, persistent database. -# Inherits username and password from default setting above. -urlid personal -url jdbc:hsqldb:file:${user.home}/db/personal;shutdown=true;ifexist=true -transiso TRANSACTION_READ_COMMITTED -# When connecting directly to a file database like this, you should -# use the shutdown connection property like this to shut down the DB -# properly when you exit the JVM. - -# This is for a hsqldb Server running with default settings on your local -# computer (and for which you have not changed the password for "SA"). -# Inherits username and password from default setting above. -# Default port 9001 -urlid localhost-sa -url jdbc:hsqldb:hsql://localhost - - - -# Template for a urlid for an Oracle database. -# Driver jar files from this century have format like "ojbc*.jar". -# Default port 1521 -urlid localhost-sa -# Avoid older drivers because they have quirks. -# You could use the thick driver instead of the thin, but I know of no reason -# why any Java app should. - -#urlid cardiff2 -# Can identify target database with either SID or global service name. -#url jdbc:oracle:thin:@//centos.admc.com/tstsid.admc -#username blaine -#password asecret - - -# Template for a TLS-encrypted HSQLDB Server. -# Remember that the hostname in hsqls (and https) JDBC URLs must match the -# CN of the server certificate (the port and instance alias that follows -# are not part of the certificate at all). -# You only need to set "truststore" if the server cert is not approved by -# your system default truststore (which a commercial certificate probably -# would be). -# Port defaults to 554. - -#urlid tls -#url jdbc:hsqldb:hsqls://db.admc.com:9001/lm2 -#username BLAINE -#password asecret -#truststore ${user.home}/ca/db/db-trust.store - - -# Template for a Postgresql database -# Driver jar files are of format like "postgresql-*.jar" -# Port defaults to 5432. -#urlid blainedb -#url jdbc:postgresql://idun.africawork.org/blainedb -#username blaine -#password asecret - -# Amazon RedShift (a fork of Postgresql) -# Driver jar files are of format like "redshift-jdbc*.jar" -# Port defaults to 5439. -#urlid redhshift -#url jdbc:redshift://clustername.hex.us-east-1.redshift.amazonaws.com/dev -#username awsuser -#password asecret - -# Template for a MySQL database. MySQL has poor JDBC support. -# The latest driver jar files are of format like "mysql-jdbc*.jar", but not -# long ago they were like "mysql-connector-java*.jar". -# Port defaults to 3306 -#urlid mysql-testdb -#url jdbc:mysql://hostname/dbname -#username root -#password asecret -# Alternatively, you can access MySQL using jdbc:mariadb URLs and driver. - -# Note that "databases" in SQL Server and Sybase are traditionally used for -# the same purpose as "schemas" with more SQL-compliant databases. - -# Template for a Microsoft SQL Server database using Microsoft's Driver -# Seems that some versions default to port 1433 and others to 1434. -# MSDN implies instances are port-specific, so can specify port or instname. -#urlid msprojsvr -# Driver jar files are of format like "mssql-jdbc-*.jar". -# Don't use older MS JDBC drivers (like SQL Server 2000 vintage) because they -# are pitifully incompetent, handling transactions incorrectly. -# I recommend that you do not use Microsoft's nonstandard format that -# includes backslashes. -#url jdbc:sqlserver://hostname;instanceName=instname;databaseName=dbname -# with port: -#url jdbc:sqlserver://hostname:1433;instanceName=instname;databaseName=dbname -#username myuser -#password asecret - -# Template for Microsoft SQL Server database using the JTDS Driver -# Looks like this project is no longer maintained, so you may be better off -# using the Microsoft driver above. -# http://jtds.sourceforge.net Jar file has name like "jtds-1.3.1.jar". -# Port defaults to 1433. -# MSDN implies instances are port-specific, so can specify port or instname. -#urlid nlyte -#username myuser -#password asecret -#url jdbc:jtds:sqlserver://myhost/nlyte;instance=MSSQLSERVER -# Where database is 'nlyte' and instance is 'MSSQLSERVER'. -# N.b. this is diff. from MS tools and JDBC driver where (depending on which -# document you read), instance or database X are specified like HOSTNAME\X. - -# Template for a Sybase database -#urlid sybase -#url jdbc:sybase:Tds:hostname:4100/dbname -#username blaine -#password asecret -# This is for the jConnect driver (requires jconn3.jar). - -# Derby / Java DB. -# Please see the Derby JDBC docs, because they have changed the organization -# of their driver jar files in recent years. Combining that with the different -# database types supported and jar file classpath chaining, and it's not -# feasible to document it adequately here. -# I'll just give one example using network service, which works with 10.15.2.0. -# Put files derbytools*.jar, derbyclient*.jar, derbyshared*.jar into a -# directory and include the path to the derbytools.jar in your classpath. -# Port defaults to 1527. -#url jdbc:derby://server:/databaseName -#username ${user.name} -#password any_noauthbydefault -# If you get the right classes into classpath, local file URLs are like: -#url jdbc:derby:path/to/derby/directory -# You can use \= to commit, since the Derby team decided (why???) -# not to implement the SQL standard statement "commit"!! -# Note that SqlTool can not shut down an embedded Derby database properly, -# since that requires an additional SQL connection just for that purpose. -# However, I've never lost data by shutting it down improperly. -# Other than not supporting this quirk of Derby, SqlTool is miles ahead of -# Derby's ij. - -# Maria DB -# With current versions, the MySQL driver does not work to access a Maria -# database (though the inverse works). -# Driver jar files are of format like "mariadb-java-client*.jar" -# Port defaults to 3306 -#urlid maria -#url jdbc:mariadb://hostname/db2 -#username blaine -#password asecret diff --git a/pom.xml b/pom.xml index 83732151..7961a9d5 100644 --- a/pom.xml +++ b/pom.xml @@ -109,6 +109,11 @@ 7.14.0 test + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.5.0 + diff --git a/src/main/java/com/uniovi/configuration/SecurityConfig.java b/src/main/java/com/uniovi/configuration/SecurityConfig.java index 0a6a2ec5..c0af5d20 100644 --- a/src/main/java/com/uniovi/configuration/SecurityConfig.java +++ b/src/main/java/com/uniovi/configuration/SecurityConfig.java @@ -1,6 +1,5 @@ package com.uniovi.configuration; -import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -38,6 +37,9 @@ public static PasswordEncoder passwordEncoder(){ @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http + .csrf(csrf -> csrf + .ignoringRequestMatchers("/api/**") + ) .authorizeHttpRequests((authorize) -> authorize .requestMatchers("/css/**", "/img/**", "/script/**").permitAll() diff --git a/src/main/java/com/uniovi/controllers/HomeController.java b/src/main/java/com/uniovi/controllers/HomeController.java index 5ae72609..f7e7e3b2 100644 --- a/src/main/java/com/uniovi/controllers/HomeController.java +++ b/src/main/java/com/uniovi/controllers/HomeController.java @@ -30,11 +30,6 @@ public String home(){ return "index"; } - @GetMapping("/api") - public String apiHome() { - return "api/apiHome"; - } - @GetMapping("/home/apikey") public String apiKeyHome(Authentication auth, Model model) { Player player = playerService.getUserByUsername(auth.getName()).get(); diff --git a/src/main/java/com/uniovi/controllers/RestApiController.java b/src/main/java/com/uniovi/controllers/RestApiController.java deleted file mode 100644 index 27bb70a0..00000000 --- a/src/main/java/com/uniovi/controllers/RestApiController.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.uniovi.controllers; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.uniovi.entities.*; -import com.uniovi.repositories.GameSessionRepository; -import com.uniovi.services.ApiKeyService; -import com.uniovi.services.RestApiService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.lang.reflect.Array; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Map; - -@RestController -public class RestApiController { - private final ApiKeyService apiKeyService; - private final RestApiService restApiService; - - @Autowired - public RestApiController(ApiKeyService apiKeyService, RestApiService restApiService) { - this.apiKeyService = apiKeyService; - this.restApiService = restApiService; - } - - @GetMapping("/api/players") - public String getPlayers(HttpServletResponse response, @RequestParam Map params) throws JsonProcessingException { - response.setContentType("application/json"); - ApiKey apiKey = getApiKeyFromParams(params); - if (apiKey == null) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - ObjectMapper objectMapper = new ObjectMapper(); - Map error = Map.of("error", "Invalid API key"); - return objectMapper.writeValueAsString(error); - } - - List players = restApiService.getPlayers(params); - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode root = objectMapper.createObjectNode(); - ArrayNode arrayNode = objectMapper.createArrayNode(); - for (Player player : players) { - arrayNode.add(player.toJson()); - } - root.put("players", arrayNode); - restApiService.logAccess(apiKey, "/api/players", params); - return root.toString(); - } - - @GetMapping("/api/questions") - public String getQuestions(HttpServletResponse response, @RequestParam Map params) throws JsonProcessingException { - response.setContentType("application/json"); - ApiKey apiKey = getApiKeyFromParams(params); - if (apiKey == null) { - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - ObjectMapper objectMapper = new ObjectMapper(); - Map error = Map.of("error", "Invalid API key"); - return objectMapper.writeValueAsString(error); - } - - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode root = objectMapper.createObjectNode(); - ArrayNode arrayNode = objectMapper.createArrayNode(); - List questions = restApiService.getQuestions(params); - for (Question question : questions) { - arrayNode.add(question.toJson()); - } - root.set("questions", arrayNode); - restApiService.logAccess(apiKey, "/api/questions", params); - return root.toString(); - } - - private ApiKey getApiKeyFromParams(Map params) { - if (!params.containsKey("apiKey")) { - return null; - } - - String apiKey = params.get("apiKey"); - return apiKeyService.getApiKey(apiKey); - } -} diff --git a/src/main/java/com/uniovi/controllers/api/PlayerApiController.java b/src/main/java/com/uniovi/controllers/api/PlayerApiController.java new file mode 100644 index 00000000..f340d376 --- /dev/null +++ b/src/main/java/com/uniovi/controllers/api/PlayerApiController.java @@ -0,0 +1,290 @@ +package com.uniovi.controllers.api; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.uniovi.dto.PlayerDto; +import com.uniovi.entities.*; +import com.uniovi.services.ApiKeyService; +import com.uniovi.services.PlayerService; +import com.uniovi.services.RestApiService; +import com.uniovi.validators.SignUpValidator; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.media.Content; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.validation.SimpleErrors; +import org.springframework.web.bind.annotation.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Tag(name = "Player API", description = "API for managing players") +@RestController +public class PlayerApiController { + private final ApiKeyService apiKeyService; + private final RestApiService restApiService; + private final SignUpValidator signUpValidator; + private final PlayerService playerService; + + @Autowired + public PlayerApiController(ApiKeyService apiKeyService, RestApiService restApiService, SignUpValidator signUpValidator, PlayerService playerService) { + this.apiKeyService = apiKeyService; + this.restApiService = restApiService; + this.signUpValidator = signUpValidator; + this.playerService = playerService; + } + + @Operation(summary = "Get players by various filters", description = "Fetch players based on the provided parameters such as username, email, id, roles.") + @Parameters({ + @Parameter(name = "apiKey", description = "API key for authentication", required = true), + @Parameter(name = "username", description = "Username of the player"), + @Parameter(name = "email", description = "Email of the player"), + @Parameter(name = "id", description = "ID of the player"), + @Parameter(name = "usernames", description = "Comma-separated list of usernames"), + @Parameter(name = "emails", description = "Comma-separated list of emails"), + @Parameter(name = "role", description = "Role of the player. Will return players that have this role."), + }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{\n" + + " \"players\":[\n" + + " {\n" + + " \"id\":1,\n" + + " \"username\":\"student1\",\n" + + " \"email\":\"student1@example.com\",\n" + + " \"roles\":[\n" + + " \"ROLE_USER\"\n" + + " ],\n" + + " \"gameSessions\":[\n" + + " {\n" + + " \"id\":1,\n" + + " \"player\":1,\n" + + " \"correctQuestions\":10,\n" + + " \"totalQuestions\":40,\n" + + " \"createdAt\":\"2024-03-04T22:44:41.067901\",\n" + + " \"finishTime\":\"2024-03-04T22:49:41.067901\",\n" + + " \"score\":0\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")} + )}), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Invalid API key\"}" + )})) + }) + @GetMapping("/api/players") + public String getPlayers(HttpServletResponse response, @RequestParam @Parameter(hidden = true) Map params) throws JsonProcessingException { + response.setContentType("application/json"); + ApiKey apiKey = getApiKeyFromParams(params); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + List players = restApiService.getPlayers(params); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode root = objectMapper.createObjectNode(); + ArrayNode arrayNode = objectMapper.createArrayNode(); + for (Player player : players) { + arrayNode.add(player.toJson()); + } + root.put("players", arrayNode); + restApiService.logAccess(apiKey, "/api/players", params); + return root.toString(); + } + + + @Operation(summary = "Create a new player account") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{ \"success\" : true, \"id\": 1 }")} + )}), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Invalid API key\"}" + )})), + @ApiResponse(responseCode = "400", description = "Could not add user due to validation errors", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"field1\":\"Error description in field 1\", \"field2\":\"Error description in field 2\"}" + )})) + }) + @PostMapping("/api/players") + public String addPlayer(@RequestHeader(name = "API-KEY") String apiKeyStr, + HttpServletResponse response, @RequestBody PlayerDto playerDto) throws JsonProcessingException { + response.setContentType("application/json"); + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + playerDto.setPasswordConfirm(playerDto.getPassword()); + + Errors err = new SimpleErrors(playerDto); + signUpValidator.validate(playerDto, err); + + if (err.hasErrors()) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode errorNode = objectMapper.createObjectNode(); + for (ObjectError error : err.getAllErrors()) { + ((ObjectNode) errorNode).put(((FieldError)error).getField(), error.getDefaultMessage()); + } + + return errorNode.toString(); + } + + Long id = playerService.addNewPlayer(playerDto).getId(); + + restApiService.logAccess(apiKey, "/api/players", Map.of("apiKey", apiKey.getKeyToken(), "user", playerDto.toString())); + return "{ \"success\" : true, \"id\": " + id + " }"; + } + + @Operation(summary = "Update a player account") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{ \"success\" : true }")} + )}), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Invalid API key\"}" + )})), + @ApiResponse(responseCode = "400", description = "Request body errors (check dropdown for more)", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Missing data", value = "{\"error\":\"No data provided\"}"), + @ExampleObject(name = "Invalid data", value = "{\"error\":\"Missing data or null data\"}"), + @ExampleObject(name = "Validation errors", value = "{\"field1\":\"Error description in field 1\", \"field2\":\"Error description in field 2\"}") + })), + @ApiResponse(responseCode = "404", description = "Player with the given ID not found", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Player not found\"}" + )})) + }) + @PatchMapping("/api/players/{id}") + public String updatePlayer(@RequestHeader(name = "API-KEY") String apiKeyStr, + HttpServletResponse response, @PathVariable Long id, @RequestBody PlayerDto playerDto) throws JsonProcessingException { + response.setContentType("application/json"); + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + Optional player = playerService.getUser(id); + if (player.isEmpty()) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Player not found"); + return objectMapper.writeValueAsString(error); + } + + if (playerDto == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "No data provided"); + return objectMapper.writeValueAsString(error); + } + + if (playerDto.getUsername() == null || playerDto.getRoles() == null || playerDto.getEmail() == null || playerDto.getPassword() == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Missing data or null data"); + return objectMapper.writeValueAsString(error); + } + + Errors err = new SimpleErrors(playerDto); + signUpValidator.validate(playerDto, err); + + if (err.hasErrors()) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode errorNode = objectMapper.createObjectNode(); + for (ObjectError error : err.getAllErrors()) { + ((ObjectNode) errorNode).put(((FieldError)error).getField(), error.getDefaultMessage()); + } + + return errorNode.toString(); + } + + playerService.updatePlayer(id, playerDto); + return "{ \"success\" : true }"; + } + + @Operation(summary = "Delete a player account") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{ \"success\" : true }")} + )}), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Invalid API key\"}" + )})), + @ApiResponse(responseCode = "404", description = "Player with the given ID not found", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Player not found\"}" + )})) + }) + @DeleteMapping("/api/players/{id}") + public String deletePlayer(@RequestHeader("API-KEY") String apiKeyStr, + HttpServletResponse response, @PathVariable Long id) throws JsonProcessingException { + response.setContentType("application/json"); + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + Optional player = playerService.getUser(id); + if (player.isEmpty()) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Player not found"); + return objectMapper.writeValueAsString(error); + } + + playerService.deletePlayer(id); + return "{ \"success\" : true }"; + } + + private ApiKey getApiKeyFromParams(Map params) { + if (!params.containsKey("apiKey")) { + return null; + } + + String apiKey = params.get("apiKey"); + return apiKeyService.getApiKey(apiKey); + } +} diff --git a/src/main/java/com/uniovi/controllers/api/QuestionsApiController.java b/src/main/java/com/uniovi/controllers/api/QuestionsApiController.java new file mode 100644 index 00000000..cdff40cf --- /dev/null +++ b/src/main/java/com/uniovi/controllers/api/QuestionsApiController.java @@ -0,0 +1,300 @@ +package com.uniovi.controllers.api; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.uniovi.dto.AnswerDto; +import com.uniovi.dto.QuestionDto; +import com.uniovi.entities.*; +import com.uniovi.services.ApiKeyService; +import com.uniovi.services.QuestionService; +import com.uniovi.services.RestApiService; +import com.uniovi.validators.QuestionValidator; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.media.Content; +import jakarta.servlet.http.HttpServletResponse; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.validation.SimpleErrors; +import org.springframework.web.bind.annotation.*; + +import org.springframework.data.domain.Pageable; +import java.util.List; + +import java.util.Map; + +@Tag(name = "Questions API", description = "API for managing questions") +@RestController +public class QuestionsApiController { + private final ApiKeyService apiKeyService; + private final RestApiService restApiService; + private final QuestionService questionService; + private final QuestionValidator questionValidator; + + @Autowired + public QuestionsApiController(ApiKeyService apiKeyService, RestApiService restApiService, QuestionService questionService, QuestionValidator questionValidator) { + this.apiKeyService = apiKeyService; + this.restApiService = restApiService; + this.questionService = questionService; + this.questionValidator = questionValidator; + } + + @Operation(summary = "Fetch questions, with different params available for management", description = "Fetch questions based on the provided parameters such as category, statement, id. The results are paged, and the page can be controlled with the page and size parameters.") + @Parameters({ + @Parameter(name = "apiKey", description = "API key for authentication", required = true), + @Parameter(name = "category", description = "Category of the question. Case sensitive"), + @Parameter(name = "statement", description = "Text contained in the statement of the question"), + @Parameter(name = "id", description = "ID of the question") + }) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{\n" + + " \"questions\":[\n" + + " {\n" + + " \"id\":11802,\n" + + " \"statement\":\"Which countries share a border with Solomon Islands?\",\n" + + " \"category\":{\n" + + " \"id\":1,\n" + + " \"name\":\"Geography\",\n" + + " \"description\":\"Questions about geography\"\n" + + " },\n" + + " \"options\":[\n" + + " {\n" + + " \"id\":46252,\n" + + " \"text\":\"Papua New Guinea\",\n" + + " \"correct\":true,\n" + + " \"question\":11802\n" + + " },\n" + + " {\n" + + " \"id\":46253,\n" + + " \"text\":\"Venezuela\",\n" + + " \"correct\":false,\n" + + " \"question\":11802\n" + + " },\n" + + " {\n" + + " \"id\":46254,\n" + + " \"text\":\"Austria\",\n" + + " \"correct\":false,\n" + + " \"question\":11802\n" + + " },\n" + + " {\n" + + " \"id\":46255,\n" + + " \"text\":\"United States of America\",\n" + + " \"correct\":false,\n" + + " \"question\":11802\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")} + )}), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = {@ExampleObject(name = "Error response", + value = "{\"error\":\"Invalid API key\"}" + )})) + }) + @GetMapping("/api/questions") + public String getQuestions(@ParameterObject Pageable pageable, HttpServletResponse response, @RequestParam @Parameter(hidden = true) Map params) throws JsonProcessingException { + response.setContentType("application/json"); + ApiKey apiKey = getApiKeyFromParams(params); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode root = objectMapper.createObjectNode(); + ArrayNode arrayNode = objectMapper.createArrayNode(); + List questions = restApiService.getQuestions(params, pageable); + for (Question question : questions) { + arrayNode.add(question.toJson()); + } + root.set("questions", arrayNode); + restApiService.logAccess(apiKey, "/api/questions", params); + return root.toString(); + } + + @Operation(summary = "Add a new question", description = "Add a new question to the database. The question must have a statement, a category, and 4 options. The correct option must be marked as such.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{\"success\": true, \"id\": 1}" + )} + )}), + @ApiResponse(responseCode = "400", description = "Bad request if the data is missing or invalid", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Error response", value = "{\"error\":\"Missing data\"}"), + @ExampleObject(name = "Validation errors", value = "{\"field1\":\"Error description in field 1\", \"field2\":\"Error description in field 2\"}") + })) + }) + @PostMapping("/api/questions") + public String addQuestion(HttpServletResponse response, @RequestHeader("API-KEY") String apiKeyStr, @RequestBody QuestionDto questionDto) throws JsonProcessingException { + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + if (questionDto == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Missing data"); + return objectMapper.writeValueAsString(error); + } + + if (questionDto.getOptions().stream().anyMatch(option -> option.isCorrect())) { + questionDto.setCorrectAnswer(questionDto.getOptions().stream().filter(option -> option.isCorrect()).findFirst().get()); + } + + Errors err = new SimpleErrors(questionDto); + questionValidator.validate(questionDto, err); + + if (err.hasErrors()) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode errorNode = objectMapper.createObjectNode(); + for (ObjectError error : err.getAllErrors()) { + ((ObjectNode) errorNode).put(((FieldError)error).getField(), error.getDefaultMessage()); + } + + return errorNode.toString(); + } + + Question q = questionService.addNewQuestion(questionDto); + + restApiService.logAccess(apiKey, "/api/questions", Map.of("apiKey", apiKeyStr, "question", questionDto.toString())); + return "{ \"success\": true, \"id\":" + q.getId() + " }"; + } + + @Operation(summary = "Update a question", description = "Update a question in the database. The question must have a statement, a category, and 4 options. The correct option must be marked as such.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{\"success\": true}" + )} + )}), + @ApiResponse(responseCode = "400", description = "Bad request if the data is missing or invalid", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Error response", value = "{\"error\":\"Missing data\"}"), + @ExampleObject(name = "Validation errors", value = "{\"field1\":\"Error description in field 1\", \"field2\":\"Error description in field 2\"}") + })), + @ApiResponse(responseCode = "404", description = "Not found if the question does not exist", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Error response", value = "{\"error\":\"Question not found\"}") + })) + }) + @PatchMapping("/api/questions/{id}") + public String updateQuestion(HttpServletResponse response, @RequestHeader("API-KEY") String apiKeyStr, + @PathVariable Long id, @RequestBody QuestionDto questionDto) throws JsonProcessingException { + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + Question q = questionService.getQuestion(id).orElse(null); + if (q == null) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Question not found"); + return objectMapper.writeValueAsString(error); + } + + if (questionDto == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Missing data"); + return objectMapper.writeValueAsString(error); + } + + if (questionDto.getOptions().stream().anyMatch(AnswerDto::isCorrect)) { + questionDto.setCorrectAnswer(questionDto.getOptions().stream().filter(option -> option.isCorrect()).findFirst().get()); + } + + Errors err = new SimpleErrors(questionDto); + questionValidator.validate(questionDto, err); + + if (err.hasErrors()) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode errorNode = objectMapper.createObjectNode(); + for (ObjectError error : err.getAllErrors()) { + ((ObjectNode) errorNode).put(((FieldError) error).getField(), error.getDefaultMessage()); + } + + return errorNode.toString(); + } + + questionService.updateQuestion(id, questionDto); + return "{ \"success\": true }"; + } + + @Operation(summary = "Delete a question", description = "Delete a question from the database") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success", + content = {@Content(mediaType = "application/json", + examples = {@ExampleObject(name = "Example response", + value = "{\"success\": true}" + )} + )}), + @ApiResponse(responseCode = "404", description = "Not found if the question does not exist", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Error response", value = "{\"error\":\"Question not found\"}") + })), + @ApiResponse(responseCode = "401", description = "Unauthorized if invalid api key", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Error response", value = "{\"error\":\"Invalid API key\"}") + })) + }) + @DeleteMapping("/api/questions/{id}") + public String deleteQuestion(HttpServletResponse response, @RequestHeader("API-KEY") String apiKeyStr, @PathVariable Long id) throws JsonProcessingException { + ApiKey apiKey = apiKeyService.getApiKey(apiKeyStr); + if (apiKey == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Invalid API key"); + return objectMapper.writeValueAsString(error); + } + + Question q = questionService.getQuestion(id).orElse(null); + if (q == null) { + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + ObjectMapper objectMapper = new ObjectMapper(); + Map error = Map.of("error", "Question not found"); + return objectMapper.writeValueAsString(error); + } + + questionService.deleteQuestion(id); + return "{ \"success\": true }"; + } + + private ApiKey getApiKeyFromParams(Map params) { + if (!params.containsKey("apiKey")) { + return null; + } + + String apiKey = params.get("apiKey"); + return apiKeyService.getApiKey(apiKey); + } +} diff --git a/src/main/java/com/uniovi/dto/AnswerDto.java b/src/main/java/com/uniovi/dto/AnswerDto.java index 20ad1e37..42275777 100644 --- a/src/main/java/com/uniovi/dto/AnswerDto.java +++ b/src/main/java/com/uniovi/dto/AnswerDto.java @@ -1,17 +1,20 @@ package com.uniovi.dto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; @Getter @Setter @AllArgsConstructor @NoArgsConstructor +@ToString public class AnswerDto { - private Long id; + + @Schema(description = "The text of the answer", example = "The answer text") private String text; + + @Schema(description = "Whether the answer is correct or not", example = "true") private boolean correct; } diff --git a/src/main/java/com/uniovi/dto/CategoryDto.java b/src/main/java/com/uniovi/dto/CategoryDto.java index 6b34b07e..0d8325b5 100644 --- a/src/main/java/com/uniovi/dto/CategoryDto.java +++ b/src/main/java/com/uniovi/dto/CategoryDto.java @@ -1,5 +1,6 @@ package com.uniovi.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,8 +14,12 @@ @NoArgsConstructor public class CategoryDto { - private Long id; + @Schema(description = "The name of the category", example = "Geography") private String name; + + @Schema(description = "The description of the category", example = "Questions about the world", hidden = true) private String description; + + @Schema(description = "The list of questions in the category", hidden = true) private List questions; } diff --git a/src/main/java/com/uniovi/dto/PlayerDto.java b/src/main/java/com/uniovi/dto/PlayerDto.java index 3b7a90b8..149cb93f 100644 --- a/src/main/java/com/uniovi/dto/PlayerDto.java +++ b/src/main/java/com/uniovi/dto/PlayerDto.java @@ -1,18 +1,27 @@ package com.uniovi.dto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; @Getter @Setter @AllArgsConstructor @NoArgsConstructor +@ToString public class PlayerDto { + + @Schema(description = "Username of the player", example = "student1") private String username; + + @Schema(description = "Email of the player", example = "student1@email.com") private String email; + + @Schema(description = "Password of the player", example = "password") private String password; + + @Schema(hidden = true) private String passwordConfirm; + + @Schema(description = "Roles of the player", example = "[\"ROLE_USER\"]") private String[] roles; } diff --git a/src/main/java/com/uniovi/dto/QuestionDto.java b/src/main/java/com/uniovi/dto/QuestionDto.java index dac83779..d97efb5f 100644 --- a/src/main/java/com/uniovi/dto/QuestionDto.java +++ b/src/main/java/com/uniovi/dto/QuestionDto.java @@ -1,9 +1,7 @@ package com.uniovi.dto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; import java.util.List; @@ -11,12 +9,21 @@ @Setter @AllArgsConstructor @NoArgsConstructor +@ToString public class QuestionDto { - private Long id; + @Schema(description = "The statement of the question") private String statement; + + @Schema(description = "The options of the question") private List options; + + @Schema(description = "The correct answer of the question", hidden = true) private AnswerDto correctAnswer; + + @Schema(description = "The category of the question") private CategoryDto category; + @Schema(description = "The language of the question") + private String language; } diff --git a/src/main/java/com/uniovi/dto/RoleDto.java b/src/main/java/com/uniovi/dto/RoleDto.java index 23565a2d..4b8244cf 100644 --- a/src/main/java/com/uniovi/dto/RoleDto.java +++ b/src/main/java/com/uniovi/dto/RoleDto.java @@ -1,14 +1,15 @@ package com.uniovi.dto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; @Getter @Setter @AllArgsConstructor @NoArgsConstructor +@ToString public class RoleDto { + + @Schema(description = "The name of the role", example = "ROLE_USER") private String name; } diff --git a/src/main/java/com/uniovi/entities/Associations.java b/src/main/java/com/uniovi/entities/Associations.java index e0a578a9..73218e2f 100644 --- a/src/main/java/com/uniovi/entities/Associations.java +++ b/src/main/java/com/uniovi/entities/Associations.java @@ -133,4 +133,28 @@ public static void removeAnswer(Question question, List answer) { //} //} } + + public static class QuestionsCategory { + /** + * Add a new association between a question and a category + * + * @param question The question + * @param category The category + */ + public static void addCategory(Question question, Category category) { + question.setCategory(category); + category.getQuestions().add(question); + } + + /** + * Remove an association between a question and a category + * + * @param question The question + * @param category The category + */ + public static void removeCategory(Question question, Category category) { + category.getQuestions().remove(question); + question.setCategory(null); + } + } } diff --git a/src/main/java/com/uniovi/entities/RestApiAccessLog.java b/src/main/java/com/uniovi/entities/RestApiAccessLog.java index bf5df136..e0c55b2e 100644 --- a/src/main/java/com/uniovi/entities/RestApiAccessLog.java +++ b/src/main/java/com/uniovi/entities/RestApiAccessLog.java @@ -1,9 +1,6 @@ package com.uniovi.entities; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -23,5 +20,7 @@ public class RestApiAccessLog { private ApiKey apiKey; private String path; + + @Column(columnDefinition = "VARCHAR(10000)") private String details; } diff --git a/src/main/java/com/uniovi/repositories/QuestionRepository.java b/src/main/java/com/uniovi/repositories/QuestionRepository.java index 16bd18dd..e7dfa216 100644 --- a/src/main/java/com/uniovi/repositories/QuestionRepository.java +++ b/src/main/java/com/uniovi/repositories/QuestionRepository.java @@ -1,5 +1,6 @@ package com.uniovi.repositories; +import com.uniovi.entities.Category; import com.uniovi.entities.Question; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -14,4 +15,10 @@ public interface QuestionRepository extends CrudRepository { @Query("SELECT q FROM Question q WHERE q.language = ?1") Page findByLanguage(Pageable pageable, String language); + + @Query("SELECT q FROM Question q WHERE q.category = ?1 AND q.language = ?2") + Page findByCategoryAndLanguage(Pageable pageable, Category category, String lang); + + @Query("SELECT q FROM Question q WHERE LOWER(q.statement) LIKE LOWER(CONCAT('%', ?1, '%')) AND q.language = ?2") + Page findByStatementAndLanguage(Pageable pageable, String statement, String language); } diff --git a/src/main/java/com/uniovi/services/PlayerService.java b/src/main/java/com/uniovi/services/PlayerService.java index a66c661f..f59669e3 100644 --- a/src/main/java/com/uniovi/services/PlayerService.java +++ b/src/main/java/com/uniovi/services/PlayerService.java @@ -59,4 +59,17 @@ public interface PlayerService { * @param player The player to generate the API key for */ void generateApiKey(Player player); + + /** + * Update the information of a player + * @param id The id of the player to update + * @param playerDto The new information of the player + */ + void updatePlayer(Long id, PlayerDto playerDto); + + /** + * Delete a player from the database + * @param id The id of the player to delete + */ + void deletePlayer(Long id); } diff --git a/src/main/java/com/uniovi/services/QuestionService.java b/src/main/java/com/uniovi/services/QuestionService.java index c89a3ae9..0b49367c 100644 --- a/src/main/java/com/uniovi/services/QuestionService.java +++ b/src/main/java/com/uniovi/services/QuestionService.java @@ -1,9 +1,12 @@ package com.uniovi.services; import com.uniovi.dto.QuestionDto; +import com.uniovi.entities.Category; import com.uniovi.entities.Question; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; +import org.springframework.data.domain.Pageable; import java.util.List; import java.util.Optional; @@ -17,6 +20,13 @@ public interface QuestionService { */ void addNewQuestion(Question question); + /** + * Add a new question to the database + * + * @param question Question to be added + */ + Question addNewQuestion(QuestionDto question); + /** * Get all the questions in the database * @@ -24,6 +34,14 @@ public interface QuestionService { */ List getAllQuestions(); + /** + * Get a page with all the questions in the database + * + * @param pageable The page to get + * @return A page with all the questions + */ + Page getQuestions(Pageable pageable); + /** * Get a question by its id * @@ -47,4 +65,35 @@ public interface QuestionService { * @return True if the answer is correct, false otherwise */ boolean checkAnswer(Long idquestion, Long idanswer); + + /** + * Get the questions of a category + * @param pageable The page to get + * @param category The category of the questions + * @param lang The language of the questions + * @return The questions of the category + */ + List getQuestionsByCategory(Pageable pageable, Category category, String lang); + + /** + * Get the questions with a statement that contains the given string + * @param pageable The page to get + * @param statement The string to search + * @param lang The language of the questions + * @return The questions with the statement that contains the string + */ + List getQuestionsByStatement(Pageable pageable, String statement, String lang); + + /** + * Update a question + * @param q The question to update + * @param questionDto The new data of the question + */ + void updateQuestion(Long id, QuestionDto questionDto); + + /** + * Delete a question + * @param id The id of the question to delete + */ + void deleteQuestion(Long id); } diff --git a/src/main/java/com/uniovi/services/RestApiService.java b/src/main/java/com/uniovi/services/RestApiService.java index 9b8570e4..a0ca59c2 100644 --- a/src/main/java/com/uniovi/services/RestApiService.java +++ b/src/main/java/com/uniovi/services/RestApiService.java @@ -4,6 +4,7 @@ import com.uniovi.entities.Player; import com.uniovi.entities.Question; +import org.springframework.data.domain.Pageable; import java.util.List; import java.util.Map; @@ -28,5 +29,5 @@ public interface RestApiService { * @param params A map with the parameters of the request * @return A list with all the questions */ - List getQuestions(Map params); + List getQuestions(Map params, Pageable pageable); } diff --git a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java index b928c030..f4fa462d 100644 --- a/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/PlayerServiceImpl.java @@ -102,4 +102,38 @@ public void generateApiKey(Player player) { System.out.println("Generated API key for " + player.getUsername() + ": " + apiKey.getKeyToken()); playerRepository.save(player); } + + @Override + public void updatePlayer(Long id, PlayerDto playerDto) { + Optional player = playerRepository.findById(id); + if (player.isEmpty()) + return; + + Player p = player.get(); + if (playerDto.getEmail() != null) + p.setEmail(playerDto.getEmail()); + if (playerDto.getUsername() != null) + p.setUsername(playerDto.getUsername()); + if (playerDto.getPassword() != null) + p.setPassword(passwordEncoder.encode(playerDto.getPassword())); + if (playerDto.getRoles() != null) { + p.getRoles().clear(); + for (String roleStr : playerDto.getRoles()) { + Role r = roleService.getRole(roleStr); + if (r != null) + Associations.PlayerRole.addRole(p, r); + else { + r = roleService.addRole(new RoleDto(roleStr)); + Associations.PlayerRole.addRole(p, r); + } + } + } + + playerRepository.save(p); + } + + @Override + public void deletePlayer(Long id) { + playerRepository.deleteById(id); + } } diff --git a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java index 6caf6b60..06bad49d 100644 --- a/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/QuestionServiceImpl.java @@ -1,12 +1,17 @@ package com.uniovi.services.impl; +import com.uniovi.dto.QuestionDto; +import com.uniovi.entities.Answer; +import com.uniovi.entities.Associations; +import com.uniovi.entities.Category; import com.uniovi.entities.Question; import com.uniovi.repositories.QuestionRepository; +import com.uniovi.services.AnswerService; +import com.uniovi.services.CategoryService; import com.uniovi.services.QuestionService; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.data.querydsl.QPageRequest; import org.springframework.stereotype.Service; @@ -15,15 +20,21 @@ import java.util.List; import java.util.Optional; import java.util.Random; +import org.springframework.data.domain.Pageable; @Service public class QuestionServiceImpl implements QuestionService { private final QuestionRepository questionRepository; + private final CategoryService categoryService; + private final AnswerService answerService; + private final Random random = new Random(); - public QuestionServiceImpl(QuestionRepository questionRepository) { + public QuestionServiceImpl(QuestionRepository questionRepository, CategoryService categoryService, AnswerService answerService) { this.questionRepository = questionRepository; + this.categoryService = categoryService; + this.answerService = answerService; } @Override @@ -31,13 +42,44 @@ public void addNewQuestion(Question question) { questionRepository.save(question); } + @Override + public Question addNewQuestion(QuestionDto question) { + Category category = categoryService.getCategoryByName(question.getCategory().getName()); + if (category == null) { + categoryService.addNewCategory(new Category(question.getCategory().getName(), question.getCategory().getDescription())); + category = categoryService.getCategoryByName(question.getCategory().getName()); + } + + List answers = new ArrayList<>(); + for (int i = 0; i < question.getOptions().size(); i++) { + Answer a = new Answer(); + a.setText(question.getOptions().get(i).getText()); + a.setCorrect(question.getOptions().get(i).isCorrect()); + answerService.addNewAnswer(a); + answers.add(a); + } + + Question q = new Question(); + q.setStatement(question.getStatement()); + q.setLanguage(question.getLanguage()); + Associations.QuestionsCategory.addCategory(q, category); + Associations.QuestionAnswers.addAnswer(q, answers); + addNewQuestion(q); + + return q; + } + @Override public List getAllQuestions() { - List l = new ArrayList<>(); - questionRepository.findAll().forEach(l::add); + List l = new ArrayList<>(questionRepository.findAll()); return l; } + @Override + public Page getQuestions(Pageable pageable) { + return questionRepository.findByLanguage(pageable, LocaleContextHolder.getLocale().getLanguage()); + } + @Override public Optional getQuestion(Long id) { return questionRepository.findById(id); @@ -67,4 +109,56 @@ public boolean checkAnswer(Long idquestion, Long idanswer) { return false; } + @Override + public List getQuestionsByCategory(Pageable pageable, Category category, String lang) { + return questionRepository.findByCategoryAndLanguage(pageable, category, lang).toList(); + } + + @Override + public List getQuestionsByStatement(Pageable pageable, String statement, String lang) { + return questionRepository.findByStatementAndLanguage(pageable, statement, lang).toList(); + } + + @Override + public void updateQuestion(Long id, QuestionDto questionDto) { + Optional q = questionRepository.findById(id); + if (q.isPresent()) { + Question question = q.get(); + question.setStatement(questionDto.getStatement()); + question.setLanguage(questionDto.getLanguage()); + Category category = categoryService.getCategoryByName(questionDto.getCategory().getName()); + if (category == null) { + categoryService.addNewCategory(new Category(questionDto.getCategory().getName(), questionDto.getCategory().getDescription())); + category = categoryService.getCategoryByName(questionDto.getCategory().getName()); + } + + List answers = new ArrayList<>(); + for (int i = 0; i < question.getOptions().size(); i++) { + Answer a = new Answer(); + a.setText(question.getOptions().get(i).getText()); + a.setCorrect(question.getOptions().get(i).isCorrect()); + answerService.addNewAnswer(a); + answers.add(a); + } + + Associations.QuestionAnswers.removeAnswer(question, question.getOptions()); + Associations.QuestionsCategory.removeCategory(question, question.getCategory()); + + Associations.QuestionAnswers.addAnswer(question, answers); + Associations.QuestionsCategory.addCategory(question, category); + questionRepository.save(question); + } + } + + @Override + public void deleteQuestion(Long id) { + Optional q = questionRepository.findById(id); + if (q.isPresent()) { + Question question = q.get(); + Associations.QuestionAnswers.removeAnswer(question, question.getOptions()); + Associations.QuestionsCategory.removeCategory(question, question.getCategory()); + questionRepository.delete(question); + } + } + } diff --git a/src/main/java/com/uniovi/services/impl/RestApiServiceImpl.java b/src/main/java/com/uniovi/services/impl/RestApiServiceImpl.java index 9661f69e..27790832 100644 --- a/src/main/java/com/uniovi/services/impl/RestApiServiceImpl.java +++ b/src/main/java/com/uniovi/services/impl/RestApiServiceImpl.java @@ -3,18 +3,17 @@ import com.mysql.cj.util.StringUtils; import com.uniovi.entities.*; import com.uniovi.repositories.RestApiLogRepository; -import com.uniovi.services.ApiKeyService; +import com.uniovi.services.CategoryService; import com.uniovi.services.PlayerService; import com.uniovi.services.QuestionService; import com.uniovi.services.RestApiService; import jakarta.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import org.springframework.data.domain.Pageable; +import java.util.*; @Service @Transactional // makes hibernate open transaction context automatically to avoid lazy-loading issues @@ -22,74 +21,77 @@ public class RestApiServiceImpl implements RestApiService { private final PlayerService playerService; private final RestApiLogRepository restApiLogRepository; private final QuestionService questionService; + private final CategoryService categoryService; @Autowired public RestApiServiceImpl(PlayerService playerService, RestApiLogRepository restApiLogRepository, - QuestionService questionService) { + QuestionService questionService, CategoryService categoryService) { this.playerService = playerService; this.restApiLogRepository = restApiLogRepository; this.questionService = questionService; + this.categoryService = categoryService; } @Override public List getPlayers(Map params) { + if (params.size() == 1) + return playerService.getUsers(); + + boolean ranOtherParams = false; + + + Set players = new HashSet<>(); if (params.containsKey("username")) { + ranOtherParams = true; Optional found = playerService.getUserByUsername(params.get("username")); - if (found.isPresent()) - return List.of(found.get()); - else - return List.of(); + found.ifPresent(players::add); } if (params.containsKey("email")) { + ranOtherParams = true; Optional found = playerService.getUserByEmail(params.get("email")); - if (found.isPresent()) - return List.of(found.get()); - else - return List.of(); - } - - if (params.containsKey("role")) { - return playerService.getUsersByRole(params.get("role")); + found.ifPresent(players::add); } if (params.containsKey("id")) { + ranOtherParams = true; try { Optional found = playerService.getUser(Long.parseLong(params.get("id"))); - if (found.isPresent()) - return List.of(found.get()); - else - return List.of(); - } catch (NumberFormatException e) { - return List.of(); + found.ifPresent(players::add); + } catch (NumberFormatException ignored) { } } if (params.containsKey("usernames")) { + ranOtherParams = true; String[] usernames = params.get("usernames").split(","); - List players = new ArrayList<>(); for (String username : usernames) { Optional found = playerService.getUserByUsername(username); - if (found.isPresent()) - players.add(found.get()); + found.ifPresent(players::add); } - return players; } if (params.containsKey("emails")) { + ranOtherParams = true; String[] emails = params.get("emails").split(","); - List filtered = new ArrayList<>(); for (String email : emails) { Optional found = playerService.getUserByEmail(email); - if (found.isPresent()) - filtered.add(found.get()); + found.ifPresent(players::add); } - return filtered; } - return playerService.getUsers(); + if (params.containsKey("role")) + { + if (!ranOtherParams) + return playerService.getUsersByRole(params.get("role")); + else + players.removeIf(p -> !p.getRoles().stream().anyMatch(r -> r.getName().equals(params.get("role")))); + } + + return players.stream().toList(); } + @Override public void logAccess(ApiKey apiKey, String path, Map params) { RestApiAccessLog log = new RestApiAccessLog(); @@ -101,18 +103,24 @@ public void logAccess(ApiKey apiKey, String path, Map params) { } @Override - public List getQuestions(Map params) { + public List getQuestions(Map params, Pageable pageable) { + String lang = LocaleContextHolder.getLocale().getLanguage(); + if (params.containsKey("lang")) { + lang = params.get("lang"); + } + if (params.containsKey("category")) { String category = params.get("category"); + Category cat = null; if (StringUtils.isStrictlyNumeric(category)) { - return questionService.getAllQuestions().stream() - .filter(q -> q.getCategory().getId() == Long.parseLong(category)) - .toList(); + Optional optCat = categoryService.getCategory(Long.parseLong(category)); + if (optCat.isPresent()) + cat = optCat.get(); } else { - return questionService.getAllQuestions().stream() - .filter(q -> q.getCategory().getName().equals(category)) - .toList(); + cat = categoryService.getCategoryByName(category); } + + return questionService.getQuestionsByCategory(pageable, cat, lang); } if (params.containsKey("id")) { try { @@ -127,11 +135,9 @@ public List getQuestions(Map params) { } if (params.containsKey("statement")) { - return questionService.getAllQuestions().stream() - .filter(q -> q.getStatement().contains(params.get("statement"))) - .toList(); + return questionService.getQuestionsByStatement(pageable, params.get("statement"), lang); } - return questionService.getAllQuestions(); + return questionService.getQuestions(pageable).toList(); } } diff --git a/src/main/java/com/uniovi/validators/QuestionValidator.java b/src/main/java/com/uniovi/validators/QuestionValidator.java new file mode 100644 index 00000000..4e08e1b3 --- /dev/null +++ b/src/main/java/com/uniovi/validators/QuestionValidator.java @@ -0,0 +1,51 @@ +package com.uniovi.validators; + +import com.uniovi.dto.AnswerDto; +import com.uniovi.dto.QuestionDto; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +@Component +public class QuestionValidator implements Validator { + @Override + public boolean supports(Class clazz) { + return QuestionDto.class.equals(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + QuestionDto question = (QuestionDto) target; + + if (question.getStatement() == null || question.getStatement().isEmpty()) { + errors.rejectValue("statement", null, + "The statement of the question cannot be empty"); + } + + if (question.getOptions() == null || question.getOptions().size() != 4) { + errors.rejectValue("options", null, + "The question must have 4 options"); + } + + if (question.getOptions().stream().anyMatch(option -> option.getText() == null || option.getText().isEmpty())) { + errors.rejectValue("options", null, + "The text of the options cannot be empty"); + } + + if (question.getOptions().stream().filter(AnswerDto::isCorrect).count() != 1) { + errors.rejectValue("options", null, + "The question must have exactly one correct option"); + } + + + if (!question.getOptions().contains(question.getCorrectAnswer())) + errors.rejectValue("correctAnswer", null, + "The correct answer must be one of the options"); + + + if (question.getCategory() == null || question.getCategory().getName() == null || question.getCategory().getName().isEmpty()) { + errors.rejectValue("category", null, + "The question must have a category"); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c7dd0e75..ca30d8d3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,4 +7,9 @@ spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver spring.datasource.url=jdbc:hsqldb:hsql://localhost:9001 spring.datasource.username=sa spring.datasource.password= -spring.jpa.hibernate.ddl-auto=update \ No newline at end of file +spring.jpa.hibernate.ddl-auto=update + +springdoc.api-docs.path=/api-docs +springdoc.swagger-ui.path=/api +springdoc.swagger-ui.operationsSorter=method +springdoc.packagesToScan=com.uniovi.controllers.api \ No newline at end of file