# HG changeset patch # User lancea # Date 1522693185 14400 # Node ID f06946e00a263b412b349da2b5e8dabede330a75 # Parent 1f76a5f8e99929cf7dddd46f3489578cefd833fc JDK-8188051-branch: add jdk.incubator.adba diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ArrayCountOperation.java --- a/src/java.sql/share/classes/java/sql2/ArrayCountOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.stream.Collector; - -/** - * A database operation that returns a count that is executed multiple times - * with multiple sets of parameter values in one database operation. The - * parameters are submitted to the database in the same order as in the - * sequences passed to the set methods. The count results are passed to the - * collector in the same order they are produced by the database. The - * value of the Operation is the final result produced by the collector. - * - * @param the type of the result of collecting the counts - */ -public interface ArrayCountOperation extends Operation { - - /** - * Set a sequence of parameter values. The value is captured and should not be - * modified before the {@link Operation} is completed. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values cannot be converted to the specified SQL type. - * - * @param id the identifier of the parameter marker to be set - * @param values the sequence of values the parameter is to be set to - * @param type the SQL type of the values to send to the database - * @return this Operation - * @throws IllegalArgumentException if the length of values is not the same as - * the length of the previously set parameter sequences or if the same id was - * passed in a previous call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, List values, SqlType type); - - /** - * Set a sequence of parameter values. Use a default SQL type determined by - * the type of the value argument. The value is captured and should not be - * modified before the {@link Operation} is completed. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values cannot be converted to the specified SQL type. - * - * @param id the identifier of the parameter marker to be set - * @param values the value the parameter is to be set to - * @return this {@link Operation} - * @throws IllegalArgumentException if the length of value is not the same as - * the length of the previously set parameter sequences or if the same id was - * passed in a previous call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, List values); - - /** - * Set a sequence of parameter values. The first parameter is captured and - * should not be modified before the {@link Operation} is completed. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values cannot be converted to the specified SQL type. - * - * @param the Java type of the individual parameter values - * @param id the identifier of the parameter marker to be set - * @param values the value the parameter is to be set to - * @param type the SQL type of the value to send to the database - * @return this Operation - * @throws IllegalArgumentException if the length of value is not the same as - * the length of the previously set parameter sequences or if the same id was - * passed in a previous call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, S[] values, SqlType type); - - /** - * Set a sequence of parameter values. Use a default SQL type determined by - * the type of the value argument. The parameter is captured and should not be - * modified before the {@link Operation} is completed. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values cannot be converted to the specified SQL type. - * - * @param the Java type of the individual parameter values - * @param id the identifier of the parameter marker to be set - * @param values the value the parameter is to be set to - * @return this Operation - * @throws IllegalArgumentException if the length of value is not the same as - * the length of the previously set parameter sequences or if the same id was - * passed in a previous call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, S[] values); - - /** - * Provide a source for a sequence of parameter values. - * - * This Operation is not executed until source is completed normally. If - * source completes exceptionally this Operation completes exceptionally with - * an IllegealArgumentException with the source's exception as the cause. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values of the source cannot be converted to the specified SQL type. - * - * If the length of the value of source is not the same as the length of all - * other parameter sequences this Operation is completed exceptionally with - * IllegalArgumentException. - * - * @param id the identifier of the parameter marker to be set - * @param source supplies the values the parameter is to be set to - * @param type the SQL type of the value to send to the database - * @return this Operation - * @throws IllegalArgumentException if the same id was passed in a previous - * call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, CompletionStage source, SqlType type); - - /** - * Provide a source for a sequence of parameter values. Use a default SQL type - * determined by the element type of the value of the source. - * - * This Operation is not executed until source is completed normally. If - * source completes exceptionally this Operation completes exceptionally with - * an IllegealArgumentException with the source's exception as the cause. - * - * The Operation is completed exceptionally with ClassCastException if any of - * the values of the source cannot be converted to the specified SQL type. - * - * If the length of the value of source is not the same as the length of all - * other parameter sequences this Operation is completed exceptionally with - * IllegalArgumentException. - * - * @param id the identifier of the parameter marker to be set - * @param source supplies the values the parameter is to be set to - * @return this {@link Operation} - * @throws IllegalArgumentException if the same id was passed in a previous - * call. - * @throws IllegalStateException if the {@link Operation} has been submitted - */ - public ArrayCountOperation set(String id, CompletionStage source); - - /** - * Provides a {@link Collector} to reduce the sequence of Counts.The result of - * the {@link Operation} is the result of calling finisher on the final - * accumulated result. If the {@link Collector} is - * {@link Collector.Characteristics#UNORDERED} counts may be accumulated out of - * order. If the {@link Collector} is - * {@link Collector.Characteristics#CONCURRENT} then the sequence of counts may be - * split into subsequences that are reduced separately and then combined. - * - * @param the type of the accumulator - * @param the type of the final result - * @param c the Collector. Not null. - * @return This ArrayCountOperation - * @throws IllegalStateException if this method had been called previously or - * this Operation has been submitted. - */ - public ArrayCountOperation collect(Collector c); - - @Override - public Submission submit(); - - @Override - public ArrayCountOperation onError(Consumer handler); - - @Override - public ArrayCountOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/Connection.java --- a/src/java.sql/share/classes/java/sql2/Connection.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,524 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.Map; -import java.util.concurrent.Executor; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * A {@link Connection} is an abstraction of a connection to a SQL database and - * a group of {@link Operation}s to be executed by that SQL database. No method - * on {@link Connection} or any of its dependent objects ({@link RowOperation} - * etc) blocks with the exception of those few methods with "Wait" in their - * name. Any other method that might block must execute any potentially blocking - * action in a thread other than the calling thread. - * - * All methods inherited from OperationGroup throw IllegalStateException if the - * the connection is not active. - */ -public interface Connection extends AutoCloseable, OperationGroup { - - /** - * Identifies the operational state of a {@link Connection}. - */ - public enum Lifecycle { - /** - * unconnected. When a connect {@link Operation} is completed successfully - * -> {@link OPEN}. If {@link deactivate} is called -> - * {@link NEW_INACTIVE}. If {@link abort} is called -> {@link ABORTING}. - * No {@link Operation}s other than connect and close will be performed. A - * Connection in this state is both 'open' and 'active'. - */ - NEW, - /** - * Unconnected and inactive. Any queued connect or close {@link Operation} - * is performed. No work can be submitted. If the {@link activate} method is - * called -> {@link NEW}. If a connect {@link Operation} completes -> - * {@link INACTIVE}. If a close {@link Operation} is executed -> - * {@link CLOSING}. If {@link abort} is called -> {@link ABORTING}. A - * Connection in this state is 'open'. - */ - NEW_INACTIVE, - /** - * fully operational. Work is queued and performed. If {@link deactivate} is - * called -> {@link INACTIVE}. If a close {@link Operation} is executed - * -> {@link CLOSING}. If {@link abort} is called -> {@link ABORTING}. - * A Connection in this state is both 'open' and 'active'. - */ - OPEN, - /** - * Not available for new work. Queued work is performed. No work can be - * submitted. If the {@link activate} method is called -> {@link OPEN}. - * If a close {@link Operation} is executed -> {@link CLOSING}. If - * {@link abort} is called -> {@link ABORTING}. A {@link Connection} in - * this state is 'open'. - */ - INACTIVE, - /** - * Work in progress is completed but no additional work is started or - * queued. Attempting to queue work throws {@link IllegalStateException}. - * When the currently executing {@link Operation}s are completed -> - * {@link CLOSED}. All other queued Operations are completed exceptionally - * with SqlSkippedException. A Connection in this state is 'closed'. - */ - CLOSING, - /** - * Work is neither queued nor performed. The currently executing - * {@link Operation}s, if any, are terminated, exceptionally if necessary. - * Any queued {@link Operation}s are terminated exceptionally with - * {@link SqlSkippedException}. Attempting to queue work throws - * {@link IllegalStateException}. When the queue is empty -< - * {@link CLOSED}. A Connection in this state is 'closed'. - */ - ABORTING, - /** - * Work is neither queued nor performed. Attempting to queue work throws - * {@link IllegalStateException}. A Connection in this state is 'closed'. - */ - CLOSED; - } - - /** - * Specifiers for how much effort to put into validating a {@link Connection}. - * The amount of effort put into checking should be non-decreasing from NONE - * (least effort) to COMPLETE (most effort). Exactly what is checked is - * implementation dependent. For example, a memory resident database driver - * might implement SOCKET and NETWORK to be the same as LOCAL. SERVER might - * verify that a database manager thread is running and COMPLETE might trigger - * the database manager thread to run a deadlock detection algorithm. - */ - public enum Validation { - /** - * isValid fails only if the {@link Connection} is closed. - */ - NONE, - /** - * {@link NONE} plus check local resources - */ - LOCAL, - /** - * {@link LOCAL} plus the server isn't obviously unreachable (dead socket) - */ - SOCKET, - /** - * {@link SOCKET} plus the network is intact (network PING) - */ - NETWORK, - /** - * {@link NETWORK} plus significant server processes are running - */ - SERVER, - /** - * everything that can be checked is working. At least {@link SERVER}. - */ - COMPLETE; - } - - /** - * A Listener that is notified of changes in a Connection's lifecycle. - */ - public interface ConnectionLifecycleListener extends java.util.EventListener { - - /** - * If this {@link java.util.EventListener} is registered with a - * {@link Connection} this method is called whenever that - * {@link Connection}'s lifecycle changes. Note that the lifecycle may have - * changed again by the time this method is called so the - * {@link Connection}'s current lifecycle may be different from the value of - * {@code current}. - * - * @param conn the {@link Connection} - * @param previous the previous value of the lifecycle - * @param current the new value of the lifecycle - */ - public void lifecycleEvent(Connection conn, Lifecycle previous, Lifecycle current); - } - - /** - * A {@link Connection} builder. A {@link Connection} is initially in the - * {@link Connection.Lifecycle#NEW} lifecycle state. It transitions to the - * {@link Connection.Lifecycle#OPEN} lifecycle state when fully initialized or - * to {@link Connection.Lifecycle#CLOSED} if initialization fails. - * - */ - public interface Builder { - - /** - * Used to execute {@link Operation}s created by this {@link Connection}. - * The default is .... - * - * @param exec provide an {@link Executor} for the {@link Connection} to use - * when executing. asynchronous work. Not {@code null}. - * @return this {@link Builder} - * @throws IllegalStateException if this method has already been called - * @throws IllegalArgumentException if the argument is {@code null} - */ - public Builder executor(Executor exec); - - /** - * Specify a property and its value for the built {@link Connection}. - * - * @param p {@link ConnectionProperty} to set. Not {@code null}. - * @param v value for the property - * @return this {@link Builder} - * @throws IllegalArgumentException if {@code p.validate(v)} does not return - * true or if this method has already been called with the property - * {@code p}. - */ - public Builder property(ConnectionProperty p, Object v); - - /** - * Return a {@link Connection} with the attributes specified. Note that the - * {@link Connection} may not be connected to a server. Call one of the - * {@link connect} convenience methods to connect the {@link Connection} to - * a server. The lifecycle of the new {@link Connection} is {@link Lifecycle#NEW}. - * - * @return a {@link Connection} - * @throws IllegalStateException if this method has already been called. - */ - public Connection build(); - } - - /** - * Returns an {@link Operation} that connects this {@link Connection} to a - * server. If the Operation completes successfully and the lifecycle is - * {@link Lifecycle#NEW} -> {@link Lifecycle#OPEN}. If lifecycle is - * {@link Lifecycle#NEW_INACTIVE} -> {@link Lifecycle#INACTIVE}. If the - * {@link Operation} completes exceptionally the lifecycle -> - * {@link Lifecycle#CLOSED}. The lifecycle must be {@link Lifecycle#NEW} or - * {@link Lifecycle#NEW_INACTIVE} when the {@link Operation} is executed. - * Otherwise the {@link Operation} will complete exceptionally with - * {@link SqlException}. - * - * Note: It is highly recommended to use the {@link connect()} convenience - * method or to use {@link DataSource#getConnection} which itself calls - * {@link connect()}. Unless there is a specific need, do not call this method - * directly. - * - * This method exists partially to clearly explain that while creating a - * {@link Connection} is non-blocking, the act of connecting to the server may - * block and so is executed asynchronously. We could write a bunch of text - * saying this but defining this method is more explicit. Given the - * {@link connect()} convenience methods there's probably not much reason to - * use this method, but on the other hand, who knows, so here it is. - * - * @return an {@link Operation} that connects this {@link Connection} to a - * server. - * @throws IllegalStateException if this {@link Connection} is in a lifecycle - * state other than {@link Lifecycle#NEW}. - */ - public Operation connectOperation(); - - /** - * Convenience method that supports the fluent style of the builder needed by - * try with resources. - * - * Note: A {@link Connection} is an {@link OperationGroup} and so has some - * advanced features that most users do not need. Management of these features - * is encapsulated in this method and the corresponding {@link close()} - * convenience method. The vast majority of users should just use these - * methods and not worry about the advanced features. The convenience methods - * do the right thing for the overwhelming majority of use cases. A tiny - * number of users might want to take advantage of the advanced features that - * {@link OperationGroup} brings to {@link Connection} and so would call - * {@link connectOperation} directly. - * - * @return this Connection - * @throws IllegalStateException if this {@link Connection} is in a lifecycle - * state other than {@link Lifecycle#NEW}. - */ - public default Connection connect() { - this.holdForMoreMembers() - .submit(); - this.connectOperation() - .submit(); - return this; - } - - /** - * Convenience method that supports the fluent style of the builder needed by - * try with resources. - * - * @param onError an Exception handler that is called if the connect - * {@link Operation} completes exceptionally. - * @return this {@link Connection} - * @throws IllegalStateException if this {@link Connection} is in a lifecycle - * state other than {@link Lifecycle#NEW}. - */ - public default Connection connect(Consumer onError) { - this.holdForMoreMembers() - .submit(); - this.connectOperation() - .submit() - .getCompletionStage() - .exceptionally(t -> { onError.accept(t); return null; } ); - return this; - } - - /** - * Returns an {@link Operation} that verifies that the resources are available - * and operational. Successful completion of that {@link Operation} implies - * that at some point between the beginning and end of the {@link Operation} - * the Connection was working properly to the extent specified by {@code depth}. - * There is no guarantee that the {@link Connection} is still working after - * completion. - * - * @param depth how completely to check that resources are available and - * operational. Not {@code null}. - * @return an {@link Operation} that will validate this {@link Connection} - * @throws IllegalStateException if this Connection is not active - */ - public Operation validationOperation(Validation depth); - - /** - * Convenience method to validate a {@link Connection}. - * - * @param depth how completely to check that resources are available and - * operational. Not {@code null}. - * @param minTime how long to wait. If 0, wait forever - * @param onError called if validation fails or times out. May be - * {@code null}. - * @return this {@link Connection} - * @throws IllegalArgumentException if {@code milliseconds} < 0 or - * {@code depth} is {@code null}. - * @throws IllegalStateException if this Connection is not active - */ - public default Connection validate(Validation depth, - Duration minTime, - Function onError) { - this.validationOperation(depth) - .timeout(minTime) - .submit() - .getCompletionStage() - .exceptionally(onError); - return this; - } - - /** - * Create an {@link Operation} to close this {@link Connection}. When the - * {@link Operation} is executed, if this {@link Connection} is open -> - * {@link Lifecycle#CLOSING}. If this {@link Connection} is closed executing - * the returned {@link Operation} is a noop. When the queue is empty and all - * resources released -> {@link Lifecycle#CLOSED}. - * - * A close {@link Operation} is never skipped. Even when the - * {@link Connection} is dependent, the default, and an {@link Operation} - * completes exceptionally, a close {@link Operation} is still executed. If - * the {@link Connection} is parallel, a close {@link Operation} is not - * executed so long as there are other {@link Operation}s or the - * {@link Connection} is held; for more {@link Operation}s. - * - * Note: It is highly recommended to use try with resources or the - * {@link close()} convenience method. Unless there is a specific need, do not - * call this method directly. - * - * @return an {@link Operation} that will close this {@link Connection}. - * @throws IllegalStateException if the Connection is not active - */ - public Operation closeOperation(); - - /** - * Create and submit an {@link Operation} to close this {@link Connection}. - * Convenience method. - * - * Note: A {@link Connection} is an {@link OperationGroup} and so has some - * advanced features; that most users do not need. Management of these - * features is encapsulated in this method and the corresponding - * {@link connect()} convenience method. The vast majority of users should - * just use these methods and not worry about the advanced features. The - * convenience methods do the right thing for the overwhelming majority of use - * cases. A tiny number of user might want to take advantage of the advanced - * features that {@link OperationGroup} brings to {@link Connection} and so - * would call {@link closeOperation} directly. - * - * @throws IllegalStateException if the Connection is not active - */ - @Override - public default void close() { - this.closeOperation() - .submit(); - this.releaseProhibitingMoreMembers(); - } - - /** - * Create a new {@link OperationGroup} for this {@link Connection}. - * - * @param the result type of the member {@link Operation}s of the returned - * {@link OperationGroup} - * @param the result type of the collected results of the member - * {@link Operation}s - * @return a new {@link OperationGroup}. - * @throws IllegalStateException if this Connection is not active - */ - public OperationGroup operationGroup(); - - /** - * Returns a new {@link Transaction} that can be used as an argument to a - * commit Operation. - * - * It is most likely an error to call this within an error handler, or any - * handler as it is very likely that when the handler is executed the next - * submitted endTransaction {@link Operation} will have been created with a different - * Transaction. - * - * @return a new {@link Transaction}. Not retained. - * @throws IllegalStateException if this Connection is not active - */ - public Transaction transaction(); - - /** - * Convenience method that submits an endTransaction {@link Operation}. This - * {@link Operation} will always attempt to commit the transaction. - * When this method is used there is no way to cause the transaction to be ended - * with a rollback. - * - * @return this {@link Connection} - */ - public default Connection commit() { - return this.commitMaybeRollback(transaction()); - } - - @Override - public default Connection commitMaybeRollback(Transaction trans) { - OperationGroup.super.commitMaybeRollback(trans); - return this; - } - - /** - * Create an endTransaction {@link Operation}, set it to rollback only, - * and submit it. Convenience method. - * - * @return this {@link OperationGroup} - */ - public default Connection rollback() { - Transaction t = transaction(); - t.setRollbackOnly(); - this.endTransactionOperation(t).submit(); - return this; - } - - /** - * Register a listener that will be called whenever there is a change in the - * lifecycle of this {@link Connection}. - * - * @param listener. Can be {@code null}. - * @throws IllegalStateException if this Connection is not active - */ - public void registerLifecycleListener(ConnectionLifecycleListener listener); - - /** - * Removes a listener that was registered by calling registerLifecycleListener. - * Sometime after this method returns the listener will stop receiving lifecycle - * events. If the listener is not registered, this is a noop. - * - * @param listener - * @throws IllegalStateException if this Connection is not active - */ - public void removeLifecycleListener(ConnectionLifecycleListener listener); - - /** - * Terminate this {@link Connection}. If lifecycle is - * {@link Lifecycle#NEW}, {@link Lifecycle#OPEN}, {@link Lifecycle#INACTIVE} - * or {@link Lifecycle#CLOSING} -> {@link Lifecycle#ABORTING} If lifecycle - * is {@link Lifecycle#ABORTING} or {@link Lifecycle#CLOSED} this is a noop. - * If an {@link Operation} is currently executing, terminate it immediately. - * Remove all remaining {@link Operation}s from the queue. {@link Operation}s - * are not skipped. They are just removed from the queue. - * - * @return this {@link Connection} - */ - public Connection abort(); - - /** - * Return the current lifecycle of this {@link Connection}. - * - * @return the current lifecycle of this {@link Connection}. - */ - public Lifecycle getLifecycle(); - - /** - * Return the set of properties configured on this {@link Connection} - * excepting any sensitive properties. Neither the key nor the value for - * sensitive properties are included in the result. Properties (other than - * sensitive properties) that have default values are included even when not - * explicitly set. Properties that have no default value and are not set - * explicitly are not included. - * - * @return a {@link Map} of property, value. Not modifiable. May be retained. - * Not {@code null}. - * @throws IllegalStateException if this Connection is not active - */ - public Map getProperties(); - - /** - * - * @return a {@link ShardingKey.Builder} for this {@link Connection} - */ - public ShardingKey.Builder shardingKeyBuilder(); - - /** - * Make this {@link Connection} ready for use. A newly created - * {@link Connection} is active. Calling this method on a {@link Connection} - * that is active is a no-op. If the lifecycle is {@link Lifecycle#INACTIVE} - * -> {@link Lifecycle#OPEN}. If the lifecycle is - * {@link Lifecycle#NEW_INACTIVE} -> {@link Lifecycle#NEW}. - * - * @return this {@link Connection} - * @throws IllegalStateException if this {@link Connection} is closed. - */ - public Connection activate(); - - /** - * Makes this {@link Connection} inactive. After a call to this method - * previously submitted Operations will be executed normally. If the lifecycle - * is {@link Lifecycle#NEW} -> {@link Lifecycle#NEW_INACTIVE}. if the - * lifecycle is {@link Lifecycle#OPEN} -> {@link Lifecycle#INACTIVE}. If - * the lifecycle is {@link Lifecycle#INACTIVE} or - * {@link Lifecycle#NEW_INACTIVE} this method is a no-op. After calling this - * method calling any method other than {@link deactivate}, {@link activate}, - * {@link abort}, or {@link getLifecycle} or submitting any member - * {@link Operation} will throw {@link IllegalStateException}. Local - * {@link Connection} state not created by {@link Connection.Builder} may not - * be preserved. - * - * Any implementation of a {@link Connection} pool is by default required to - * call {@code deactivate} when putting a {@link Connection} into a pool. The - * implementation is required to call {@code activate} when removing a - * {@link Connection} from a pool so the {@link Connection} can be used. An - * implementation of a {@link Connection} pool may have an optional mode where - * it does not call {@code deactivate}/{@code activate} as required above. The - * behavior of the pool and {@link Connection}s cached in the pool in such a - * mode is entirely implementation dependent. - * - * @return this {@link Connection} - * @throws IllegalStateException if this {@link Connection} is closed - */ - public Connection deactivate(); - - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ConnectionProperty.java --- a/src/java.sql/share/classes/java/sql2/ConnectionProperty.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -/** - * An attribute of a {@link Connection} that can be configured to influence its - * behavior. Implementors of this interface define the properties of - * {@link Connection}s. The {@link Connection.Builder#property} method is used to set the values - * of {@link Connection} properties. - * - */ -public interface ConnectionProperty { - - /** - * Return the name of this {@link ConnectionProperty}. - * - * @return the name of this {@link ConnectionProperty} - */ - public String name(); - - /** - * Return the type of the value of this {@link ConnectionProperty}. Any value - * set for this property must be assignable to this type. - * - * @return the type of the values of this {@link ConnectionProperty} - */ - public Class range(); - - /** - * Determine whether a value is valid for this {@link ConnectionProperty}. Returns - * {@code true} if {@code value} is valid and {@code false} otherwise. - * - * @param value a value for this {@link ConnectionProperty} - * @return {@code true} iff {@code value} is valid for this {@link ConnectionProperty} - */ - public default boolean validate(Object value) { - return (value == null && this.range() == Void.class) || this.range().isInstance(value); - } - - /** - * Return the value for this property to use if no other value is set. For - * this to have any meaning for a user defined property the property must be - * registered with the {@link DataSource} by calling - * {@link DataSource.Builder#registerConnectionProperty}. - * - * @return the default value or {@code null} if there is no default value - */ - public Object defaultValue(); - - /** - * Returns true if this {@link ConnectionProperty} is contains sensitive information - * such as a password or encryption key. - * - * @return true iff this is sensitive - */ - public boolean isSensitive(); - - /** - * Returns an {@link Operation} that will configure the {@link Connection} to have the - * specified property value. May return {@code null} if no {@link Operation} needed. The - * returned {@link Operation} is a member of group but is not submitted. - * - * Called by {@link Connection.Builder#build()} to configure a {@link Connection} as specified - * in the {@link Connection.Builder#property} method. ConnectionProperties known to the implementation - * may return {@code null} and rely on the implementation to do the right thing. - * - * @param group an {@link OperationGroup} which will be the container of the returned - * {@link Operation}, if any - * @param value the value to which the property is to be set. May be null if - * {@link range()} is {@link Void}. - * @return an {@link Operation} or null - * @throws IllegalStateException if it is not possible to configure the - * {@link Connection} as specified. - * @throws IllegalArgumentException if {@code this.validate(value)} returns {@code false} - */ - public default Operation configureOperation(OperationGroup group, Object value) { - if (validate(value)) { - return null; - } - else { - throw new IllegalArgumentException(value.toString() + " is invalid"); - } - } - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/CountOperation.java --- a/src/java.sql/share/classes/java/sql2/CountOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * An {@link Operation} that returns a count. - * - * @param the type of the result of the {@link Operation} - * @see ParameterizedCountOperation - */ -public interface CountOperation extends Operation { - - /** - * Sets the result processor for this {@link Operation}. - * - * @param function processes the count produced by executing this - * {@link Operation} and returns the result - * @return this {@link CountOperation} - * @throws IllegalStateException if this method has been called previously - */ - public CountOperation apply(Function function); - - @Override - public CountOperation onError(Consumer handler); - - @Override - public CountOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/DataSource.java --- a/src/java.sql/share/classes/java/sql2/DataSource.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.util.LinkedList; -import java.util.List; -import java.util.function.Consumer; - -/** - * Uses the builder pattern to get a {@link Connection}. A {@link getConnection} - * method is provided as a convenience. - */ -public interface DataSource - extends AutoCloseable { - - /** - * Instances of this type are used to build {@link DataSource}s. This type is - * immutable once configured. No property can be set more than once. No - * property can be set after {@link build} is called. - */ - public interface Builder { - - /** - * A convenience method for setting the {@link JdbcConnectionProperty#URL}. - * - * @param url the value to be set for {@link JdbcConnectionProperty#URL} - * @return this {@link Builder} - * @see connectionProperty - */ - public default Builder url(String url) { - return connectionProperty(JdbcConnectionProperty.URL, url); - } - - /** - * A convenience method for setting the {@link JdbcConnectionProperty#USER}. - * - * @param name the value to be set for {@link JdbcConnectionProperty#USER} - * @return this {@link Builder} - * @see connectionProperty - */ - public default Builder username(String name) { - return connectionProperty(JdbcConnectionProperty.USER, name); - } - - /** - * A convenience method for setting the {@link JdbcConnectionProperty#PASSWORD}. - * - * @param password the value to be set for {@link JdbcConnectionProperty#PASSWORD} - * @return this {@link Builder} - * @see connectionProperty - */ - public default Builder password(String password) { - return connectionProperty(JdbcConnectionProperty.PASSWORD, password); - } - - /** - * Specify the value of a {@link Connection} property that will be set by default on - * all {@link Connection}s produced by this {@link DataSource}. A different value can be set - * for a particular {@link Connection} via {@link Connection.Builder#property}. - * - * @param property the {@link ConnectionProperty} to be set. May not be {@code null}. - * @param value the value to be set for {@code property} - * @return this {@link Builder} - * @throws IllegalArgumentException if {@code property.validate(value)} does not - * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if - * this property has been specified previously to this method or - * {@link connectionProperty}. - * @throws IllegalStateException if {@link build} has previously been called. - */ - public Builder defaultConnectionProperty(ConnectionProperty property, Object value); - - /** - * Specify the value of a {@link Connection} property that will be set on all - * {@link Connection}s produced by the built {@link DataSource}. Attempting to set a - * different value via {@link Connection.Builder#property} will throw - * {@link IllegalArgumentException}. - * - * @param property the {@link ConnectionProperty} to set. May not be {@code null}. - * @param value the value to set as the default for {@code property} - * @return this {@link Builder} - * @throws IllegalArgumentException if {@code property.validate(value)} does not - * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if - * this property has been specified previously to this method or - * {@link defaultConnectionProperty}. - * @throws IllegalStateException if {@link build} has previously been called. - */ - public Builder connectionProperty(ConnectionProperty property, Object value); - - /** - * Make a user defined property known to the implementation. One reason to - * do this is so the default value of the property will be used. If the - * {@link DataSource} doesn't know about the property then it cannot know to set the - * default value. Registering a property already known to the DataSource is - * a no-op. - * - * @param property the {@link ConnectionProperty} to make known. May not be {@code null}. - * @return this Builder - * @throws IllegalStateException if {@link build} has previously been called. - */ - public Builder registerConnectionProperty(ConnectionProperty property); - - /** - * Return a DataSource configured as specified. - * - * @return a configured {@link DataSource}. Not {@code null}. - * @throws IllegalArgumentException if unable to return a {@link DataSource} due to - * problems with the configuration such is missing or conflicting properties. - */ - public DataSource build(); - } - - /** - * Returns a {@link Connection} builder. By default that builder will return - * {@link Connection}s with the {@code ConnectionProperty}s specified when creating this - * DataSource. Default and unspecified {@link ConnectionProperty}s can be set with - * the returned builder. - * - * @return a new {@link Connection} builder. Not {@code null}. - */ - public Connection.Builder builder(); - - /** - * Returns a {@link Connection} that has a submitted connect {@link Operation}. Convenience - * method for use with try with resources. - * - * @return a {@link Connection} - */ - public default Connection getConnection() { - return builder().build().connect(); - } - - /** - * Returns a {@link Connection} that has a submitted connect {@link Operation} with an error - * handler. Convenience method for use with try with resources. The error - * handle handles errors in the connect {@link Operation}. - * - * @param handler for errors in the connect {@link Operation} - * @return a {@link Connection} - */ - public default Connection getConnection(Consumer handler) { - return builder().build().connect(handler); - } - - /** - * Translates a SQL string from the format specified by the format argument - * to a format that can be used to create {@link Operation}s for the {@link Connection}s - * provided by this {@link DataSource}. - * - * ISSUE: Just an idea - * - * @param format not {@code null} - * @param source SQL in the format specified by {@code format}. Not {@code null}. - * @return SQL in the format supported by this {@link DataSource}. Not {@code null}. - * @throws IllegalArgumentException if the {@code format} is not supported - * @throws SqlException if the {@link DataSource} cannot translate the SQL - */ - public default String translateSql(String format, String source) throws SqlException { - throw new IllegalArgumentException("Unsupported format: \"" + format + "\""); - } - - /** - * Return a list of the source formats accepted by the {@link translateSql} method. - * - * ISSUE: Just an idea - * - * @return an array of Strings each of which identifies a supported format - */ - public default List supportedTranslateSqlFormats() { - return new LinkedList<>(); - } - - @Override - public void close(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/DataSourceFactory.java --- a/src/java.sql/share/classes/java/sql2/DataSourceFactory.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -/** - * This interface supports injecting a {@link DataSourceFactory}. The SPI - * mechanism will register {@link DataSourceFactory} implementations with the - * given name. - * - */ -public interface DataSourceFactory { - - /** - * Uses SPI to find a {@link DataSourceFactory} with the requested name or - * {@code null} if one is not found. - * - * @param name the name that identifies the factory - * @return a {@link DataSourceFactory} for {@code name} or {@code null} if one - * is not found - */ - public static DataSourceFactory forName(String name) { - return DataSourceFactoryManager.instance().forName(name); - } - - /** - * Registers the given factory with. A newly-loaded factory class should call - * the method {@code registerDataSourceFactory} to make itself known. If the - * factory is currently registered, no action is taken. - * - * @param factory the new JDBC DataSourceFactory that is to be registered with - * the {@code DataSourceFactoryManager} - * @exception NullPointerException if {@code factory} is null - */ - public static void registerDataSourceFactory(DataSourceFactory factory) { - registerDataSourceFactory(factory, null); - } - - /** - * Registers the given factory with the {@code DataSourceFactoryManager}. A - * newly-loaded factory class should call the method - * {@code registerDataSourceFactory} to make itself known. If the factory is - * currently registered, no action is taken. - * - * @param factory the new DataSourceFactory that is to be registered - * @param da the {@code DataSourceFactoryAction} implementation to be used - * when {@code DataSourceFactoryManager#deregisterDataSourceFactory} is called - * @exception NullPointerException if {@code factory} is null - */ - public static void registerDataSourceFactory(DataSourceFactory factory, - DataSourceFactoryAction da) { - DataSourceFactoryManager.instance().registerDataSourceFactory(factory, da); - } - - /** - * Removes the specified factory from the list of registered factories. - *

- * If a {@code null} value is specified for the factory to be removed, then no - * action is taken. - *

- * If a security manager exists and its {@code checkPermission} denies - * permission, then a {@code SecurityException} will be thrown. - *

- * If the specified factory is not found in the list of registered factories, - * then no action is taken. If the factory was found, it will be removed from - * the list of registered factories. - *

- * If a {@code DataSourceFactoryAction} instance was specified when the JDBC - * factory was registered, its deregister method will be called prior to the - * factory being removed from the list of registered factories. - * - * @param factory the DataSourceFactory to remove - * @throws SecurityException if a security manager exists and its - * {@code checkPermission} method denies permission to deregister a factory. - * - * @see SecurityManager#checkPermission - */ - public static void deregisterDataSourceFactory(DataSourceFactory factory) { - DataSourceFactoryManager.instance().deregisterDataSourceFactory(factory); - } - - /** - * Returns a new {@link DataSource} builder. - * - * @return a {@link DataSource} builder. Not {@code null}. - */ - public java.sql2.DataSource.Builder builder(); - - /** - * Name by which this factory is registered. - * - * @return the name of this factory - */ - public String getName(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/DataSourceFactoryAction.java --- a/src/java.sql/share/classes/java/sql2/DataSourceFactoryAction.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -/** - * An interface that must be implemented when a {@linkplain DataSourceFactory} wants to be - * notified by {@code DataSourceFactory.class}. - *

- * A {@code DataSourceFactoryAction} implementation is not intended to be used - * directly by applications. A DataSourceFactory may choose - * to create its {@code DataSourceFactoryAction} implementation in a private class - * to avoid it being called directly. - *

- * A DataSourceFactory static initialization block must call - * {@linkplain DataSourceFactory#registerDataSourceFactory(java.sql2.DataSourceFactory, java.sql2.DataSourceFactoryAction) } in order - * to inform {@code DataSourceFactory} which {@code DataSourceFactoryAction} implementation to - * call when the DataSourceFactory is de-registered. - * @since 1.8 - */ -public interface DataSourceFactoryAction { - /** - * Method called by - * {@linkplain DataSourceFactory#deregisterDataSourceFactory(DataSourceFactory) } - * to notify the DataSourceFactory that it was de-registered. - *

- * The {@code deregister} method is intended only to be used by DataSourceFactories - * and not by applications. Implementations are recommended to not implement - * {@code DataSourceFactoryAction} in a public class. If there are active - * connections to the database at the time that the {@code deregister} - * method is called, it is implementation specific as to whether the - * connections are closed or allowed to continue. Once this method is - * called, it is implementation specific as to whether the implementation may - * limit the ability to create new connections to the database, invoke - * other {@code DataSourceFactory} methods or throw a {@code Exception}s. - * Consult your implementation vendor's documentation for additional information - * on its behavior. - * @see DataSourceFactory#registerDataSourceFactory(java.sql.DataSourceFactory, java.sql.DataSourceFactoryAction) - * @see DataSourceFactory#deregisterDataSourceFactory(DataSourceFactory) - * @since 1.8 - */ - void deregister(); - -} \ No newline at end of file diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/DataSourceFactoryManager.java --- a/src/java.sql/share/classes/java/sql2/DataSourceFactoryManager.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; -import java.util.Iterator; -import java.util.ServiceLoader; -import java.util.concurrent.CopyOnWriteArrayList; -//TODO import jdk.internal.reflect.CallerSensitive; -//TODO import jdk.internal.reflect.Reflection; - -/** - * This class manages a list of registered DataSourceFactories. - */ -class DataSourceFactoryManager { - - private static final DataSourceFactoryManager SOLE_INSTANCE = new DataSourceFactoryManager(); - private static final Permission DEREGISTER_DATASOURCEFACTORY_PERMISSION = null; - - static DataSourceFactoryManager instance() { - return SOLE_INSTANCE; - } - - private final CopyOnWriteArrayList registeredDataSourceFactories = - new CopyOnWriteArrayList<>(); - - private DataSourceFactoryManager() { - } - - /*HACK*/ void println(Object ... x) { } - - /** - * Attempts to locate a factory with the given name. - * The DataSourceFactoryManager attempts to select an appropriate factory from - * the set of registered ADBA factories. - * - * @param name the name of a DataSourceFactory - */ -//TODO @CallerSensitive - DataSourceFactory forName(String name) { - - println("DataSourceFactoryManager.getDataSourceFactory(\"" + name + "\")"); - - Class callerClass = null; //TODO Reflection.getCallerClass(); - - // Walk through the loaded registeredDataSourceFactories attempting to locate - // one with the given name - for (FactoryInfo aDataSourceFactory : registeredDataSourceFactories) { - // If the caller does not have permission to load the factory then - // skip it. - if(isDataSourceFactoryAllowed(aDataSourceFactory.factory, callerClass)) { - if(aDataSourceFactory.factory.getName().equals(name)) { - // Success! - println("getDataSourceFactory returning " + aDataSourceFactory.factory.getClass().getName()); - return (aDataSourceFactory.factory); - } - - } else { - println(" skipping: " + aDataSourceFactory.factory.getClass().getName()); - } - } - println("getDataSourceFactory: no suitable factory"); - return null; - } - - - - // Indicates whether the class object that would be created if the code calling - // DataSourceFactoryManager is accessible. - private boolean isDataSourceFactoryAllowed(DataSourceFactory factory, Class caller) { - ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; - return isDataSourceFactoryAllowed(factory, callerCL); - } - - private boolean isDataSourceFactoryAllowed(DataSourceFactory factory, ClassLoader classLoader) { - boolean result = false; - if(factory != null) { - Class aClass = null; - try { - aClass = Class.forName(factory.getClass().getName(), true, classLoader); - } catch (Exception ex) { - result = false; - } - result = ( aClass == factory.getClass() ) ? true : false; - } - return result; - } - - private void loadInitialDataSourceFactories() { - String factories; - try { - factories = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty("adba.factories")); - } catch (Exception ex) { - factories = null; - } - // If the factory is packaged as a Service Provider, load it. - // Get all the factories through the classloader - // exposed as a java.sql2.DataSourceFactory.class service. - // ServiceLoader.load() replaces the sun.misc.Providers() - - AccessController.doPrivileged((PrivilegedAction) () -> { - ServiceLoader loadedDataSourceFactories = ServiceLoader.load(DataSourceFactoryManager.class); - Iterator factoriesIterator = loadedDataSourceFactories.iterator(); - - /* Load these factories, so that they can be instantiated. - * It may be the case that the factory class may not be there - * i.e. there may be a packaged factory with the service class - * as implementation of java.sql2.DataSourceFactory but the actual class - * may be missing. In that case a java.util.ServiceConfigurationError - * will be thrown at runtime by the VM trying to locate - * and load the service. - * - * Adding a try catch block to catch those runtime errors - * if factory not available in classpath but it's - * packaged as service and that service is there in classpath. - */ - try{ - while(factoriesIterator.hasNext()) { - factoriesIterator.next(); - } - } catch(Throwable t) { - // Do nothing - } - return null; - }); - - println("DataSourceFactoryManager.initialize: adba.factories = " + factories); - - if (factories == null || factories.equals("")) { - return; - } - String[] factoriesList = factories.split(":"); - println("number of DataSourceFactories:" + factoriesList.length); - for (String aDataSourceFactory : factoriesList) { - try { - println("DataSourceFactoryManager.Initialize: loading " + aDataSourceFactory); - Class.forName(aDataSourceFactory, true, - ClassLoader.getSystemClassLoader()); - } catch (Exception ex) { - println("DataSourceFactoryManager.Initialize: load failed: " + ex); - } - } - } - - /** - * Registers the given factory with the {@code DataSourceFactoryManager}. - * A newly-loaded factory class should call - * the method {@code registerDataSourceFactory} to make itself - * known to the {@code DataSourceFactoryManager}. If the factory is currently - * registered, no action is taken. - * - * @param factory the new JDBC DataSourceFactory that is to be registered with the - * {@code DataSourceFactoryManager} - * @exception SQLException if a database access error occurs - * @exception NullPointerException if {@code factory} is null - */ - synchronized void registerDataSourceFactory(DataSourceFactory factory) { - - registerDataSourceFactory(factory, null); - } - - /** - * Registers the given factory with the {@code DataSourceFactoryManager}. - * A newly-loaded factory class should call - * the method {@code registerDataSourceFactory} to make itself - * known to the {@code DataSourceFactoryManager}. If the factory is currently - * registered, no action is taken. - * - * @param factory the new JDBC DataSourceFactory that is to be registered with the - * {@code DataSourceFactoryManager} - * @param da the {@code DataSourceFactoryAction} implementation to be used when - * {@code DataSourceFactoryManager#deregisterDataSourceFactory} is called - * @exception SQLException if a database access error occurs - * @exception NullPointerException if {@code factory} is null - * @since 1.8 - */ - synchronized void registerDataSourceFactory(DataSourceFactory factory, - DataSourceFactoryAction da) { - - /* Register the factory if it has not already been added to our list */ - if(factory != null) { - registeredDataSourceFactories.addIfAbsent(new FactoryInfo(factory, da)); - } else { - // This is for compatibility with the original DataSourceFactoryManager - throw new NullPointerException(); - } - - println("registerDataSourceFactory: " + factory); - - } - - /** - * Removes the specified factory from the {@code DataSourceFactoryManager}'s list of - * registered factories. - *

- * If a {@code null} value is specified for the factory to be removed, then no - * action is taken. - *

- * If a security manager exists and its {@code checkPermission} denies - * permission, then a {@code SecurityException} will be thrown. - *

- * If the specified factory is not found in the list of registered factories, - * then no action is taken. If the factory was found, it will be removed - * from the list of registered factories. - *

- * Usage Note: Frequently use of this method will require a type witness - * to enable correct type inferencing. - *


-   *   conn.<List<Integer>>arrayCountOperation(sql)
-   *     .set ...
-   *     .collect ...
-   *     .submit ...
-   * 
- * - * @param the result type of the returned {@link ArrayCountOperation} - * @param sql SQL to be executed. Must return an update count. - * @return a new {@link ArrayCountOperation} that is a member of this - * {@link OperationGroup} - */ - public ArrayCountOperation arrayCountOperation(String sql); - - /** - * Return a new {@link CountOperation}. - * - * @param the result type of the returned {@link CountOperation} - * @param sql SQL to be executed. Must return an update count. - * @return an new {@link CountOperation} that is a member of this - * {@link OperationGroup} - * - */ - public ParameterizedCountOperation countOperation(String sql); - - /** - * Return a new {@link Operation} for a SQL that doesn't return any result, - * for example DDL. - * - * @param sql SQL for the {@link Operation}. - * @return a new {@link Operation} that is a member of this - * {@link OperationGroup} - */ - public Operation operation(String sql); - - /** - * Return a new {@link OutOperation}. The SQL must return a set of zero or - * more out parameters or function results. - * - * @param the result type of the returned {@link OutOperation} - * @param sql SQL for the {@link Operation}. Must return zero or more out - * parameters or function results. - * @return a new {@link OutOperation} that is a member of this - * {@link OperationGroup} - */ - public OutOperation outOperation(String sql); - - /** - * Return a {@link ParameterizedRowOperation}. - * - * @param the type of the result of the returned {@link ParameterizedRowOperation} - * @param sql SQL for the {@link Operation}. Must return a row sequence. - * @return a new {@link ParameterizedRowOperation} that is a member of this - * {@link OperationGroup} - */ - public ParameterizedRowOperation rowOperation(String sql); - - /** - * Return a {@link StaticMultiOperation}. - * - * @param the type of the result of the returned - * {@link StaticMultiOperation} - * @param sql SQL for the {@link Operation} - * @return a new {@link StaticMultiOperation} that is a member of this - * {@link OperationGroup} - */ - public StaticMultiOperation staticMultiOperation(String sql); - - /** - * Return a {@link DynamicMultiOperation}. Use this when the number and type - * of the results is not knowable. - * - * @param the type of the result of the returned - * {@link DynamicMultiOperation} - * @param sql SQL for the {@link Operation} - * @return a new {@link DynamicMultiOperation} that is a member of this - * {@link OperationGroup} - */ - public DynamicMultiOperation dynamicMultiOperation(String sql); - - /** - * Return an {@link Operation} that ends the database transaction. - * The transaction is ended with a commit unless the {@link Transaction} has - * been {@link Transaction#setRollbackOnly} in which - * case the transaction is ended with a rollback. - * - * The type argument {@link S} of the containing {@link OperationGroup} must be - * a supertype of {@link TransactionOutcome}. - * - * @param trans the Transaction that determines whether the Operation does a - * database commit or a database rollback. - * @return an {@link Operation} that will end the database transaction. - * @throws IllegalStateException if this {@link OperationGroup} has been submitted and - * is not held or is parallel. - */ - public Operation endTransactionOperation(Transaction trans); - - /** - * Convenience method that creates and submits a endTransaction {@link Operation} - * that commits by default but can be set to rollback by calling - * {@link Transaction#setRollbackOnly}. - * - * @param trans the Transaction that determines whether the Operation is a - * database commit or a database rollback. - * @return this {@link OperationGroup} - * @throws IllegalStateException if this {@link OperationGroup} has been submitted and - * is not held or is parallel. - */ - public default OperationGroup commitMaybeRollback(Transaction trans) { - this.endTransactionOperation(trans).submit(); - return this; - } - - /** - * Return a {@link LocalOperation}. - * - * @return a LocalOperation - * @throws IllegalStateException if this OperationGroup has been submitted and - * is not held - */ - public LocalOperation localOperation(); - - /** - * Returns a Flow.Processor that subscribes to a sequence of Operations and - * produces a sequence of corresponding Submissions. The Operations must be - * members of this OperationGroup. Calling Subscription.onNext with any - * Operation that is not a member of this OperationGroup, that is was not - * created by calling one of the Operation factory methods on this - * OperationGroup, will cause the Subscription to be canceled and call - * Subscriber.onError with IllegalArgumentException. The method - * Subscription.onNext will call submit on each Operation it is passed and - * publish the resulting Submission. Since an Operation can only be submitted - * once, submitting an Operation and calling onNext with that submitted - * Operation will cause the Subscription to be canceled and Subscriber.onError - * to be called with IllegalStateException. The Processor does not retain - * Submissions to produce to a subsequently attached Subscriber. - * - * If there is no Subscriber to the Processor, the Processor will request - * Operations as appropriate. If there is a Subscriber to the Processor, the - * Processor will request Operations no faster than the Subscriber requests - * Submissions. - * - * Each call to this method returns a new Flow.processor. The Submissions - * published to each Processor are exactly those generated by calling submit - * on the Operations passed as arguments to onNext on the same Processor. - * Calling this method while there is an active Processor will throw - * IllegalStateException. - * - * Note: If any Operation is submitted directly, that is by calling submit - * rather than passing it to onNext, the Submission returned by the submit - * call will not be published. - * - * @return a Flow.Processor that accepts Operations and generates Submissions - * @throws IllegalStateException if there is an active Processor - */ - public Flow.Processor, Submission> operationProcessor(); - - /** - * Supply a {@link Logger} for the implementation of this - * {@link OperationGroup} to use to log significant events. Exactly what - * events are logged, at what Level the events are logged and with what - * parameters is implementation dependent. All member {@link Operation}s of - * this {@link OperationGroup} will use the same {@link Logger} except a - * member {@link OperationGroup} that is supplied with a different - * {@link Logger} uses that {@link Logger}. - * - * Supplying a {@link Logger} configured with a - * {@link java.util.logging.MemoryHandler} with the - * {@link java.util.logging.MemoryHandler#pushLevel} set to - * {@link java.util.logging.Level#WARNING} will result in no log output in - * normal operation. In the event of an error the actions leading up to the - * error will be logged. - * - * Implementation Note: Implementations are encouraged to log the creation of - * this {@link OperationGroup} set to {@link java.util.logging.Level#INFO}, the - * creation of member {@link Operation}s at the - * {@link java.util.logging.Level#CONFIG} level, and execution of member - * {@link Operation}s at the {@link java.util.logging.Level#FINE} level. - * Detailed information about the execution of member {@link Operation}s may - * be logged at the {@link java.util.logging.Level#FINER} and - * {@link java.util.logging.Level#FINEST} levels. Errors in the execution of - * user code should be logged at the {@link java.util.logging.Level#WARNING} - * Level. Errors in the implementation code should be logged at the - * {@link java.util.logging.Level#SEVERE} Level. - * - * @param logger used by the implementation to log significant events - * @return this {@link OperationGroup} - */ - public OperationGroup logger(Logger logger); - - @Override - public OperationGroup timeout(Duration minTime); -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/OutOperation.java --- a/src/java.sql/share/classes/java/sql2/OutOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * An {@link ParameterizedOperation} for which the result is a set of out parameter - * values and/or function results. As the SQL is vendor specific, how parameters - * are represented in the SQL is itself vendor specific. - * - * @param the type of the result of this {@link Operation} - */ -public interface OutOperation extends ParameterizedOperation { - - /** - * Register an out parameter identified by the given id. - * - * @param id the parameter identifier - * @param type the SQL type of the value of the parameter - * @return this {@link OutOperation} - * @throws IllegalArgumentException if id is not a parameter marker in the SQL - * @throws IllegalStateException if this method has been called previously on - * this {@link Operation} with the same id or this {@link OutOperation} has been submitted - */ - public OutOperation outParameter(String id, SqlType type); - - /** - * Provide a processor that will handle the result of executing the SQL. - * - * @param processor the {@link Function} that will be called to process the result of - * this {@link OutOperation} - * @return this {@link OutOperation} - * @throws IllegalStateException if this method has been called previously on - * this {@link Operation} or this {@link Operation} has been submitted. - */ - public OutOperation apply(Function processor); - - // Covariant overrides - - @Override - public OutOperation onError(Consumer handler); - - @Override - public OutOperation set(String id, Object value); - - @Override - public OutOperation set(String id, Object value, SqlType type); - - @Override - public OutOperation set(String id, CompletionStage source); - - @Override - public OutOperation set(String id, CompletionStage source, SqlType type); - - @Override - public OutOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ParameterizedCountOperation.java --- a/src/java.sql/share/classes/java/sql2/ParameterizedCountOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * A {@link ParameterizedCountOperation} is a {@link ParameterizedOperation} that returns a count. - * - * @param the type of the result of this {@link Operation} - */ -public interface ParameterizedCountOperation extends ParameterizedOperation, CountOperation { - - /** - * Returns a {@link RowOperation} to process the auto-generated keys, if any, returned - * by this {@link Operation}. If no keys are named the columns of the returned - * rows are implementation dependent. If keys are specified the columns of the - * returned rows are the keys. The {@link RowOperation} must be submitted before this - * {@link Operation} is submitted. If it has not submitting this {@link Operation} will - * result throw {@link IllegalStateException}. - * - * ISSUE: Should this be in {@link CountOperation}? - * - * @param keys the names of the returned columns or null. - * @return A RowOperation that will process the auto-generated keys - * @throws IllegalStateException if this method has already been called on this - * {@link Operation} or if this {@link Operation} has already been submitted. - */ - public RowOperation returning(String ... keys); - - // Covariant overrides - - @Override - public ParameterizedCountOperation onError(Consumer handler); - - @Override - ParameterizedCountOperation apply(Function processor); - - @Override - public ParameterizedCountOperation set(String id, Object value); - - @Override - public ParameterizedCountOperation set(String id, Object value, SqlType type); - - @Override - public ParameterizedCountOperation set(String id, CompletionStage source); - - @Override - public ParameterizedCountOperation set(String id, CompletionStage source, SqlType type); - - @Override - public ParameterizedCountOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ParameterizedOperation.java --- a/src/java.sql/share/classes/java/sql2/ParameterizedOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.util.concurrent.CompletionStage; - -/** - * An Operation that has in parameters. - * - * As the SQL is vendor specific, how parameters are represented in the SQL is - * itself vendor specific. - * - * For positional parameters, those where all parameters are indicated by the - * same character sequence, for example '?', it is recommended that the - * parameter id be the decimal integer representation of the parameter number. - * - * A SQL structured type passed as an argument to a set method must be created - * by the same {@link Connection} that the created the - * {@link ParameterizedOperation}. If not {@link IllegalArgumentException} is - * thrown. A SQL structured type is one of - * {@link SqlArray}, {@link SqlBlob}, {@link SqlClob}, {@link SqlRef} or - * {@link SqlStruct}. This limitation holds recursively for all components of - * a SQL structured type. An implementation may relax this constraint. - * - * @param the type of the result of this {@link Operation} - */ -public interface ParameterizedOperation extends Operation { - - /** - * Set a parameter value. The value is captured and should not be modified - * before the {@link Operation} is completed. - * - * @param id the identifier of the parameter marker to be set - * @param value the value the parameter is to be set to - * @param type the SQL type of the value to send to the database - * @return this Operation - */ - public ParameterizedOperation set(String id, Object value, SqlType type); - - /** - * Set a parameter value. Use a default SQL type determined by the type of the - * value argument. The value is captured and should not be modified before the - * {@link Operation} is completed. - * - * @param id the identifier of the parameter marker to be set - * @param value the value the parameter is to be set to - * @return this {@link Operation} - */ - public ParameterizedOperation set(String id, Object value); - - /** - * Set a parameter value to be the value of a - * {@link java.util.concurrent.CompletionStage}. The {@link Operation} will - * not be executed until the {@link java.util.concurrent.CompletionStage} is - * completed. This method allows submitting {@link Operation}s that depend on - * the result of previous {@link Operation}s rather than requiring that the - * dependent {@link Operation} be submitted only when the previous - * {@link Operation} completes. - * - * @param id the identifier of the parameter marker to be set - * @param source the {@link java.util.concurrent.CompletionStage} that provides - * the value the parameter is to be set to - * @param type the SQL type of the value to send to the database - * @return this {@link Operation} - */ - public ParameterizedOperation set(String id, CompletionStage source, SqlType type); - - /** - * Set a parameter value to be the future value of a - * {@link java.util.concurrent.CompletionStage}. The {@link Operation} will - * not be executed until the {@link java.util.concurrent.CompletionStage} is - * completed. This method allows submitting {@link Operation}s that depend on - * the result of previous {@link Operation}s rather than requiring that the - * dependent {@link Operation} be submitted only when the previous - * {@link Operation} completes. Use a default SQL type determined by the type - * of the value of the {@link java.util.concurrent.CompletionStage} - * argument. - * - * @param id the identifier of the parameter marker to be set - * @param source the {@link java.util.concurrent.CompletionStage} that - * provides the value the parameter is to be set to - * @return this {@link Operation} - */ - public ParameterizedOperation set(String id, CompletionStage source); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ParameterizedRowOperation.java --- a/src/java.sql/share/classes/java/sql2/ParameterizedRowOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.stream.Collector; - -/** - * An Operation that accepts parameters and processes a sequence of rows. - * - * @param the type of the result of this {@link Operation} - */ -public interface ParameterizedRowOperation extends ParameterizedOperation, RowOperation { - - // Covariant overrides - - @Override - public ParameterizedRowOperation onError(Consumer handler); - - @Override - public ParameterizedRowOperation fetchSize(long rows) throws IllegalArgumentException; - - @Override - public ParameterizedRowOperation collect(Collector c); - - @Override - public ParameterizedRowOperation set(String id, Object value, SqlType type); - - @Override - public ParameterizedRowOperation set(String id, CompletionStage source, SqlType type); - - @Override - public ParameterizedRowOperation set(String id, CompletionStage source); - - @Override - public ParameterizedRowOperation set(String id, Object value); - - @Override - public ParameterizedRowOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/Result.java --- a/src/java.sql/share/classes/java/sql2/Result.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.util.concurrent.CompletionStage; - -/** - * All or part of the result of a database operation (lower case). - * - * A {@link Result} is valid only for the duration of the call it is passed to. Once - * that call has returned, the {@link Result} passed to that call is invalid and any - * calls to it throw {@link IllegalStateException}. {@link Result}s are not required to be - * thread-safe. - * - */ -public interface Result { - - /** - * A {@link Result} that is just a number of rows modified, a {@link Long}. - * - * Note: It is certainly true that this is not needed; {@link Long} could be used - * instead. Seems like there might be a documentational advantage to having - * this type. If you don't like it, just mentally replace it with {@link Long} - * everywhere it appears. - */ - public static interface Count extends Result { - - /** - * - * @return - */ - public long getCount(); - } - - /** - * A {@link Result} where the components can be retrieved by name. What - * constitutes a name is implementation dependent. - * - */ - public static interface ResultMap extends Result { - - /** - * Return the value indicated by the {@code id}. The {@code id} may be either the id for an - * OUT parameter marker or for a column. See {@link OutOperation} and - * {@link RowOperation}. - * - * @param the type of the returned value - * @param id the name of the column or OUT parameter marker - * @param type the value indicated by {@code id} is converted to this type - * @return a value of type {@code T} - * @throws IllegalArgumentException if id is not the identifier of a value - * in this {@link ResultMap} - * @throws IllegalStateException if the call that was passed this {@link ResultMap} has - * ended - * @throws ClassCastException if the returned value cannot be converted to the - * specified type -- ISSUE: Not really a class cast. Maybe a new unchecked exception. - */ - public T get(String id, Class type); - - /** - * Returns a {@code {@link String}[]} that contains the identifiers that reference the - * values of this {@link ResultMap} in the same order these values are returned by the - * database. A {@code null} value in the array means there is a returned value for - * which no identifier was defined. There is no way to retrieve such a - * value. - * - * By default the values in the array are the identifier portion of the out - * parameter markers in the SQL. Alternatively the implementation may assign - * other identifiers, typically column names or aliases. If there - * are values that have no associated identifier the corresponding value in - * the array will be null. - * - * @return an array containing the value identifiers. Not {@code null}. - * @throws IllegalStateException if the call that was passed this {@link ResultMap} has - * ended - */ - public String[] getIdentifiers(); - } - - /** - * Used by {@link OutOperation} to expose the out parameters of a call. - */ - public static interface OutParameterMap extends ResultMap { - } - - /** - * Used by {@link RowOperation} to expose each row of a row sequence. - */ - public static interface Row extends ResultMap { - - /** - * The count of {@link Row}s in the {@link Row} sequence preceeding this {@link Row}. For the first - * row in the Row sequence the {@link rowNumber} is 0. - * - * @return the count of {@link Row}s in the {@link Row} sequence preceeding this {@link Row} - * @throws IllegalStateException if the call that was passed this {@link Result} has - * ended - */ - public long rowNumber(); - - /** - * Is this the last {@link Row} of the row sequence. If true then the result of the - * call that was passed this {@link Row} is the result of the {@link Operation}. - * - * @return a {@link java.util.concurrent.CompletionStage} the value of which - * will be true iff this the last {@link Row} of a row sequence and false otherwise - * @throws IllegalStateException if the call that was passed this {@link Result} has - * ended - */ - public CompletionStage isLast(); - - /** - * Terminate processing of the rows in this {@link RowOperation}. The result of the - * call that was passed this {@link Row} will be the result of the {@link Operation}. No - * further rows in the row sequence will be processed. All subsequent rows, - * if any, will be ignored. Any rows already fetched will not be processed. - * Any rows not yet fetched may or may not be fetched. If fetched they will - * not be processed. - * - * @throws IllegalStateException if the call that was passed this {@link Result} has - * ended - */ - public void cancel(); - - } - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/RowOperation.java --- a/src/java.sql/share/classes/java/sql2/RowOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.util.function.Consumer; -import java.util.stream.Collector; - -/** - * A {@link RowOperation} is a database operation that returns a row sequence. - * - * @param the type of the result of this {@link Operation} - */ -public interface RowOperation extends Operation { - - /** - * A hint to the implementation of how many rows to fetch in each database - * access. Implementations are free to ignore it. - * - * @param rows suggested number of rows to fetch per access - * @return this {@link RowOperation} - * @throws IllegalArgumentException if row < 1 - * @throws IllegalStateException if this method had been called previously or - * this Operation has been submitted. - */ - public RowOperation fetchSize(long rows) throws IllegalArgumentException; - - /** - * Provides a {@link Collector} to reduce the sequence of rows.The result of - * the {@link Operation} is the result of calling finisher on the final - * accumulated result. If the {@link Collector} is - * {@link Collector.Characteristics#UNORDERED} rows may be accumulated out of - * order. If the {@link Collector} is - * {@link Collector.Characteristics#CONCURRENT} then the sequence of rows may be - * split into subsequences that are reduced separately and then combined. - * - * @param the type of the accumulator - * @param the type of the final result - * @param c the Collector. Not null. - * @return This RowOperation - * @throws IllegalStateException if this method had been called previously or - * this Operation has been submitted. - */ - public RowOperation collect(Collector c); - - @Override - public RowOperation onError(Consumer handler); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/RowProcessorOperation.java --- a/src/java.sql/share/classes/java/sql2/RowProcessorOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Flow; -import java.util.function.Consumer; - -/** - * - * @param the type of the result of the {@link Operation} - */ -public interface RowProcessorOperation extends ParameterizedOperation { - - /** DRAFT - * Accepts a Processor that subscribes to a stream of Rows and publishes - * a stream of result values. The last result value published is the result - * of the Operation. If no value is published the result of Operation is null. - * - * The result of this Operation is the last value passed to the onNext method - * of the Subscriber passed to rowProcessor.subscribe. If onComplete - * is called before any value is passed to onNext this Operation is completed - * with null. If onError is called this Operation completes exceptionally - * with the passed exception. If neither onComplete or onError is called - * this Operation will complete exceptionally after the inactivity timeout - * expires. - * - * Calling Row.cancel is the same as calling Subscription.cancel on the Row - * Subscription. - * - * @param rowToResult subscribes to a stream of Result.Rows and publishes a - * stream of results of type T - * @return this RowProcessorOperation - */ - public RowProcessorOperation rowProcessor(Flow.Processor rowToResult); - - /** DRAFT - * Sets the minimum time the Operation will wait for Processor activity before - * terminating. If all of the following hold for some time exceeding minTime, - * this Operation will be completed exceptionally with - * {@link java.util.concurrent.TimeoutException}. - *
    - *
  • no calls to the onNext, onComplete, or - * onError methods of the Subscriber passed to rowToResult.subscribe
  • - *
  • the demand for Rows is zero or all rows have been published
  • - *
- * If the Operation can publish no more rows either because all rows have - * been published or because the demand for rows is 0 and rowToResult - * has neither published a result nor terminated the stream and this state has - * continued for at least minTime, the Operation is completed exceptionally. - * - * The default value is one minute. - * - * Note: The minTime parameter value must be small to guarantee that the - * Connection does not hang for long periods. The default is large enough - * that it most likely is insignificant for most apps, but small enough to - * kick loose a hung Connection in semi-reasonable time. - * - * @param minTime - * @return this RowProcessorOperation - */ - public RowProcessorOperation inactivityTimeout(Duration minTime); - - // Covariant overrides - - @Override - public RowProcessorOperation onError(Consumer handler); - - @Override - public RowProcessorOperation set(String id, Object value, SqlType type); - - @Override - public RowProcessorOperation set(String id, CompletionStage source, SqlType type); - - @Override - public RowProcessorOperation set(String id, CompletionStage source); - - @Override - public RowProcessorOperation set(String id, Object value); - - @Override - public RowProcessorOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/ShardingKey.java --- a/src/java.sql/share/classes/java/sql2/ShardingKey.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -/** - * Interface used to indicate that this object represents a Sharding Key. A - * {@link ShardingKey} instance is only guaranteed to be compatible with the - * data source instance that it was derived from. A {@link ShardingKey} is - * created using {@link Builder}. - *

- * The following example illustrates the use of {@link Builder} to create a - * {@link ShardingKey}: - *

- * {@code
- *
- *     DataSource ds = new MyDataSource();
- *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
- *                           .subkey("abc", JDBCType.VARCHAR)
- *                           .subkey(94002, JDBCType.INTEGER)
- *                           .build();
- * }
- * 
- *

- * - * A {@link ShardingKey} is used for specifying a - * {@link JdbcConnectionProperty#SHARDING_KEY} or a - * {@link JdbcConnectionProperty#SHARDING_GROUP_KEY}. Databases that support - * composite Sharding may use a * to specify a additional level of partitioning - * within to specify a additional level of partitioning within the Shard. - *

- * The following example illustrates the use of {@link Builder} to create a - * {@link JdbcConnectionProperty#SHARDING_GROUP_KEY} for an eastern region with - * a {@link JdbcConnectionProperty#SHARDING_KEY} specified for the Pittsburgh - * branch office: - *

- * {@code
- *
- *     DataSource ds = new MyDataSource();
- *     ShardingKey superShardingKey = ds.shardingKeyBuilder()
- *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
- *                           .build();
- *     ShardingKey shardingKey = ds.shardingKeyBuilder()
- *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
- *                           .build();
- *     Connection con = ds.builder()
- *                           .property(SHARDING_GROUP_KEY, superShardingKey)
- *                           .property(SHARDING_KEY, shardingKey)
- *                           .build();
- * }
- * 
- */ -public interface ShardingKey { - - /** - * A builder created from a {@link DataSource} or object, used to create a - * {@link ShardingKey} with sub-keys of supported data types. Implementations - * must support JDBCType.VARCHAR and may also support additional data types. - *

- * The following example illustrates the use of {@link Builder} to create a - * {@link ShardingKey}: - *

-   * {@code
-   *
-   *     DataSource ds = new MyDataSource();
-   *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
-   *                           .subkey("abc", JDBCType.VARCHAR)
-   *                           .subkey(94002, JDBCType.INTEGER)
-   *                           .build();
-   * }
-   * 
- */ - public interface Builder { - - /** - * This method will be called to add a subkey into a Sharding Key object - * being built. The order in which subkey method is called is important as - * it indicates the order of placement of the subkey within the Sharding - * Key. - * - * @param subkey contains the object that needs to be part of shard sub key - * @param subkeyType sub-key data type of type java.sql.SQLType - * @return this builder object - */ - public Builder subkey(Object subkey, SqlType subkeyType); - - /** - * Returns an instance of the object defined by this builder. - * - * @return The built object - */ - public ShardingKey build(); - } - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlArray.java --- a/src/java.sql/share/classes/java/sql2/SqlArray.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.TYPE; -import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Identifies a type that represents an ARRAY SQL type. - * Any type to which this annotation is applied must either extend or implement - * java.util.List. Additionally the type must have at least one of the following: - *
    - *
  • a public zero-arg constructor
  • - *
  • a public constructor Constructor(int initialCapacity)
  • - *
  • a public constructor Constructor(<? super List<?>>)
  • - *
  • a public static factory method of(<? super List<?>>)
  • - *
- * If more than one of the above is supported it is implementation dependent which - * is used. - * - * - */ -@Target({TYPE}) -@Retention(RUNTIME) -public @interface SqlArray { - public String elementSqlTypeName(); -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlBlob.java --- a/src/java.sql/share/classes/java/sql2/SqlBlob.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.nio.channels.AsynchronousByteChannel; -import java.util.concurrent.CompletionStage; - -/** - * A reference to a BINARY LARGE OBJECT in the attached database. - * - */ -public interface SqlBlob extends AutoCloseable { - - /** - * Return an {@link Operation} that will release the temporary resources - * associated with this {@link SqlBlob}. - * - * @return an {@link Operation} that will release the temporary resources - * associated with this {@link SqlBlob}. - */ - public Operation closeOperation(); - - @Override - public default void close() { - this.closeOperation().submit(); - } - - /** - * Return a {@link Operation} that fetches the position of this {@link SqlBlob}. - * The position is 1-based. Position 0 is immediately before the first byte in - * the {@link SqlBlob}. Position 1 is the first byte in the {@link SqlBlob}, etc. - * Position {@link length()} is the last byte in the {@link SqlBlob}. - * - * Position is between 0 and length + 1. - * - * @return a {@link Operation} that returns the position of this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public Operation getPositionOperation(); - - /** - * Get the position of this {@link SqlBlob}. The position is 1-based. Position 0 - * is immediately before the first byte in the {@link SqlBlob}. Position 1 is the - * first byte in the {@link SqlBlob}, etc. Position {@link length()} is the last - * byte in the {@link SqlBlob}. - * - * Position is between 0 and length + 1. - * - * ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java - * does? - * - * @return a future which value is the 1-based position of this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public default CompletionStage getPosition() { - return getPositionOperation().submit().getCompletionStage(); - } - - /** - * Return a {@link Operation} that fetches the length of this {@link SqlBlob}. - * - * @return a {@link Operation} that returns the length of this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public Operation lengthOperation(); - - /** - * Get the length of this {@link SqlBlob}. - * - * @return a future which value is the number of bytes in this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public default CompletionStage length() { - return lengthOperation().submit().getCompletionStage(); - } - - /** - * Return a {@link Operation} that sets the position of this {@link SqlBlob}. If - * offset exceeds the length of this {@link SqlBlob} set position to the length + - * 1 of this {@link SqlBlob}, ie one past the last byte. - * - * @param offset a non-negative number - * @return a {@link Operation} that sets the position of this {@link SqlBlob} - * @throws IllegalArgumentException if {@code offset} is less than 0 - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public Operation setPositionOperation(long offset); - - /** - * Set the position of this {@link SqlBlob}. If offset exceeds the length of this - * {@link SqlBlob} set position to the length + 1 of this {@link SqlBlob}, ie one - * past the last byte. - * - * @param offset the 1-based position to set - * @return this {@link SqlBlob} - * @throws IllegalArgumentException if offset is less than 0 - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public default SqlBlob setPosition(long offset) { - setPositionOperation(offset).submit(); - return this; - } - - /** - * Return a {@link Operation} to set the position to the beginning of the next - * occurrence of the target after the position. If there is no such occurrence - * set the position to 0. - * - * @param target a {@link SqlBlob} created by the same {@link Connection} - * containing the byte sequence to search for - * @return a {@link Operation} that locates {@code target} in this - * {@link SqlBlob} - * @throws IllegalArgumentException if {@code target} was created by some - * other {@link Connection} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public Operation locateOperation(SqlBlob target); - - /** - * Set the position to the beginning of the next occurrence of the target - * after the position. If there is no such occurrence set the position to 0. - * - * @param target the byte sequence to search for - * @return this {@link SqlBlob} - * @throws IllegalArgumentException if {@code target} was created by some - * other {@link Connection} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed - */ - public default SqlBlob locate(SqlBlob target) { - locateOperation(target).submit(); - return this; - } - - /** - * Return an {@link Operation} to set the position to the beginning of the - * next occurrence of the target after the position. If there is no such - * occurrence set the position to 0. - * - * @param target the byte sequence to search for. Not {@code null}. Captured. - * @return a {@link Operation} that locates {@code target} in this - * {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public Operation locateOperation(byte[] target); - - /** - * Set the position to the beginning of the next occurrence of the target - * after the position. If there is no such occurrence set the position to 0. - * - * @param target the byte sequence to search for - * @return this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public default SqlBlob locate(byte[] target) { - locateOperation(target).submit(); - return this; - } - - /** - * Return a {@link Operation} that truncates this {@link SqlBlob} so that the - * current position is the end of the {@link SqlBlob}. If the position is N, then - * after {@link trim()} the length is N - 1. The position is still N. This - * will fail if position is 0. - * - * @return a {@link Operation} that trims the length of this {@link SqlBlob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed or position is 0. - */ - public Operation trimOperation(); - - /** - * Truncate this {@link SqlBlob} so that the current position is the end of the - * {@link SqlBlob}. If the position is N, then after {@link trim()} the length is - * N - 1. The position is still N. This will fail if position is 0. - * - * @return this SqlBlob - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed or position is 0. - */ - public default SqlBlob trim() { - trimOperation().submit(); - return this; - } - - /** - * Return a {@link java.nio.channels.Channel} that can be used to read bytes from the - * {@link SqlBlob} beginning at the position. Reading bytes from the returned - * {@link java.nio.channels.Channel} advances the position. - * - * Each call to a read method that fetches bytes from the server creates and - * submits a virtual {@link Operation} to fetch those bytes. This virtual - * {@link Operation} is executed in sequence with other {@link Operation}s and - * may be skipped if an error occurs. - * - * @return a read-only byte {@link java.nio.channels.Channel} beginning at the position. - * @throws IllegalStateException if the {@link Connection} that created this - SqlBlob is closed. - */ - public AsynchronousByteChannel getReadChannel(); - - /** - * Return a {@link java.nio.channels.Channel} that can be used to write bytes - * to this {@link SqlBlob} beginning at the position. Bytes written overwrite - * bytes already in the {@link SqlBlob}. Writing bytes to the returned - * {@link java.nio.channels.Channel} advances the position. - * - * Each call to a write method that flushes bytes to the server creates and - * submits a virtual {@link Operation} to flush those bytes. This virtual - * {@link Operation} is executed in sequence with other {@link Operation}s and - * may be skipped if an error occurs. - * - * ISSUE: Can the app read bytes from a write - * {@link java.nio.channels.Channel}? If so then maybe remove - * {@link getReadChannel} and add a read-only flag to this method, renamed - * {@code getChannel}. - * - * @return a writable byte {@link java.nio.channels.Channel} beginning at the - * position. - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlBlob} is closed. - */ - public AsynchronousByteChannel getWriteChannel(); -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlClob.java --- a/src/java.sql/share/classes/java/sql2/SqlClob.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.io.Reader; -import java.io.Writer; -import java.util.concurrent.CompletionStage; - -/** - * A reference to a CHARACTER LARGE OBJECT in the attached database. - * - */ -public interface SqlClob extends AutoCloseable { - - /** - * Return an {@link Operation} that will release the temporary resources - * associated with this {@link SqlClob}. - * - * @return an {@link Operation} that will release the temporary resources - * associated with this {@link SqlClob}. - */ - public Operation closeOperation(); - - @Override - public default void close() { - this.closeOperation().submit(); - } - - /** - * Return a {@link Operation} that fetches the position of this {@link SqlClob}. - * Position 0 is immediately before the first char in the {@link SqlClob}. - * Position 1 is the first char in the {@link SqlClob}, etc. Position - * {@link length()} is the last char in the {@link SqlClob}. - * - * Position is between 0 and length + 1. - * - * @return an {@link Operation} that returns the position of this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed.; - */ - public Operation getPositionOperation(); - - /** - * Get the position of this {@link SqlClob}. Position 0 is immediately before the - * first char in the {@link SqlClob}. Position 1 is the first char in the - * {@link SqlClob}, etc. Position {@link length()} is the last char in the SqlClob. - - Position is between 0 and length + 1. - - ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java - does? - * - * @return a future which value is the position of this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public default CompletionStage getPosition() { - return getPositionOperation().submit().getCompletionStage(); - } - - /** - * Return a {@link Operation} that fetches the length of this {@link SqlClob}. - * - * @return a {@link Operation} that returns the length of this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public Operation lengthOperation(); - - /** - * Get the length of this {@link SqlClob}. - * - * @return a {@link java.util.concurrent.Future} which value is the number of - * chars in this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public default CompletionStage length() { - return lengthOperation().submit().getCompletionStage(); - } - - /** - * Return an {@link Operation} that sets the position of this {@link SqlClob}. If - * {@code offset} exceeds the length of this {@link SqlClob} set position to the - * length + 1 of this {@link SqlClob}, ie one past the last char. - * - * @param offset a non-negative number - * @return a {@link Operation} that sets the position of this {@link SqlClob} - * @throws IllegalArgumentException if {@code offset} is less than 0 - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public Operation setPositionOperation(long offset); - - /** - * Set the position of this {@link SqlClob}. If {@code offset} exceeds the length - * of this {@link SqlClob} set position to the length + 1 of this {@link SqlClob}, - * ie one past the last char. - * - * @param offset the 1-based position to set - * @return this {@link SqlClob} - * @throws IllegalArgumentException if {@code offset} is less than 0 - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public default SqlClob setPosition(long offset) { - setPositionOperation(offset).submit(); - return this; - } - - /** - * Return an {@link Operation} to set the position to the beginning of the - * next occurrence of the target after the position. If there is no such - * occurrence set the position to 0. - * - * @param target a {@link SqlClob} created by the same {@link Connection} - * containing the char sequence to search for - * @return an {@link Operation} that locates {@code target} in this - * {@link SqlClob} - * @throws IllegalArgumentException if {@code target} was created by some - * other {@link Connection} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public Operation locateOperation(SqlClob target); - - /** - * Set the position to the beginning of the next occurrence of the target - * after the position. If there is no such occurrence set the position to 0. - * - * @param target the char sequence to search for - * @return this {@link SqlClob} - * @throws IllegalArgumentException if {@code target} was created by some - * other {@link Connection} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed - */ - public default SqlClob locate(SqlClob target) { - locateOperation(target).submit(); - return this; - } - - /** - * Return an {@link Operation} to set the position to the beginning of the - * next occurrence of the target after the position. If there is no such - * occurrence set the position to 0. - * - * @param target the char sequence to search for. Not {@code null}. Captured. - * @return an {@link Operation} that locates {@code target} in this - * {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public Operation locateOperation(CharSequence target); - - /** - * Set the position to the beginning of the next occurrence of the target - * after the position. If there is no such occurrence set the position to 0. - * - * @param target the char sequence to search for - * @return this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed. - */ - public default SqlClob locate(CharSequence target) { - locateOperation(target).submit(); - return this; - } - - /** - * Return an {@link Operation} that truncates this {@link SqlClob} so that the - * current position is the end of the {@link SqlClob}. If the position is N, then - * after trim() the length is N - 1. The position is still N. This will fail - * if position is 0. - * - * @return an {@link Operation} that trims the length of this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed or position is 0. - */ - public Operation trimOperation(); - - /** - * Truncate this {@link SqlClob} so that the current position is the end of the - * {@link SqlClob}. If the position is N, then after {@link trim()} the length is - * N - 1. The position is still N. This will fail if position is 0. - * - * @return this {@link SqlClob} - * @throws IllegalStateException if the {@link Connection} that created this - * {@link SqlClob} is closed or position is 0. - */ - public default SqlClob trim() { - trimOperation().submit(); - return this; - } - - /** - * Returns a {@link Reader} for the characters in this {@link SqlClob}. - * Characters are read starting at the current position. Each character read - * advances the position by one. - * - * ISSUE: There is no character analog to - * {@link java.nio.channels.AsynchronousByteChannel}. It is trivial to - * construct a {@link java.io.Reader} from an - * {@link java.nio.channels.AsynchronousByteChannel} however. - * - * @return a Reader for the characters in this SqlClob - */ - public Reader getReader(); - - /** - * Returns a Writer for this {@link SqlClob}. Characters are written starting at - * the current position. Each character written advances the position by one. - * - * ISSUE: There is no character analog to - * {@link java.nio.channels.AsynchronousByteChannel}. It is trivial to - * construct a {@link java.io.Writer} from an - * {@link java.nio.channels.AsynchronousByteChannel} however. - * - * @return a Writer for the characters of this SqlClob - */ - public Writer getWriter(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlColumns.java --- a/src/java.sql/share/classes/java/sql2/SqlColumns.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.CONSTRUCTOR; -import static java.lang.annotation.ElementType.METHOD; -import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - - -/** - * Identifies a constructor or static factory method that can be used to construct - * an instance of the containing type when the type is passed to {@link Result.ResultMap#get}. - * The method or constructor must be public. - * - * An instance of this type will be constructed by calling the factory method or - * constructor. Each element in the value of this annotation is used as a column - * identifier. The value of that column is passed to the corresponding parameter - * of the annotated method or constructor. The id argument to {@link Result.ResultMap#get} is - * prefixed to the column identifiers. - * - * The following pseudo-code describes how an instance is constructed. - * - * {@code - *
    int i = 0;
- *   String[] columns = methodOrConstructor.getAnnotation(SqlColumns.class).value();
- *   Object[] args = new Object[columns.length];
- *   for (String columnName : columns)
- *     args[i] = resultMap.get(prefix + columnName, parameterTypes[i++];
- *   instance = methodOrConstructor.invoke(null, args);
} - * - */ -@Retention(RUNTIME) -@Target({CONSTRUCTOR, METHOD}) -public @interface SqlColumns { - - /** - * The column names corresponding to the parameters of the factory method or - * constructor to construct an instance of this type. There must be exactly one - * column name for each parameter of the annotated method or constructor. - * - * @return the column names in the order returned by the database - */ - public String[] value(); -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlException.java --- a/src/java.sql/share/classes/java/sql2/SqlException.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -/** - *

- * An exception that provides information on a database access error or other - * errors. - * - *

- * Each SqlException provides several kinds of information: - *

    - *
  • a string describing the error. This is used as the Java Exception - * message, available via the method getMesasge. - *
  • a "SQLstate" string, which follows either the XOPEN SQLstate conventions - * or the SQL:2003 conventions. The values of the SQLState string are described - * in the appropriate spec. The DatabaseMetaData method - * getSQLStateType can be used to discover whether the driver - * returns the XOPEN type or the SQL:2003 type. - *
  • an integer error code that is specific to each vendor. Normally this - * will be the actual error code returned by the underlying database. - *
  • the causal relationship, if any for this SqlException. - *
  • the SQL string that was executing when the error occurred. - *
  • the position in the SQL string where the error was detected. - *
- */ -public class SqlException extends RuntimeException { - - // Fields - - /** - */ - private String sqlState = null; - - /** - */ - private int vendorCode = -1; - - /** - * The SQL string that was sent to the database. - */ - private String sqlString = null; - - /** - * The index of the first character in SQL where an error is detected. Zero - * based. - */ - private int position = -1; - - // Constructors - - private SqlException() { - super(); - } - - /** - * - * @param message - * @param cause - * @param sqlState - * @param vendorCode - * @param sql - * @param position - */ - public SqlException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) { - super(message, cause); - this.sqlState = sqlState; - this.vendorCode = vendorCode; - this.sqlString = sql; - this.position = position; - } - - // Methods - - /** - * Retrieves the SqlState for this SqlException object. - * - * @return the SQLState value - */ - public String getSqlState() { - return (sqlState); - } - - /** - * Retrieves the vendor-specific exception code for this - * SqlException object. - * - * @return the vendor's error code - */ - public int getVendorCode() { - return (vendorCode); - } - - /** - * Get the position. - * - * @return the index of the first character in sql where an error is detected. - * Zero based. - */ - public int getPosition() { - return position; - } - - /** - * Get the sql. - * - * @return the SQL string sent to the database - */ - public String getSqlString() { - return sqlString; - } -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlParameter.java --- a/src/java.sql/share/classes/java/sql2/SqlParameter.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.METHOD; -import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - - -/** - * Identifies a method the result of which will be bound to a parameter in a SQL - * statement when an instance of the containing type is passed to - * {@link ParameterizedOperation#set}. - * - * The following pseudo-code describes how an instance is used to set parameter - * values: - * - * {@code - *
    for (Method getter : annotatedMethods) {
- *       Annotation parameter = getter.getAnnotation(SqlParameter.class);
- *       op.set(prefix + parameter.marker(), method.invoke(instance), parameter.sqlType());
- *   }
} - * - */ -@Retention(RUNTIME) -@Target({METHOD}) -public @interface SqlParameter { - - /** - * The marker for SQL parameter that the result of this method will be bound to. - * - * @return the name that identifies the parameter in the SQL - */ - public String marker(); - - /** - * The SQL type of the value bound to the parameter. - * Must be either the name of an enum in {@link java.sql2.JdbcType} or the fully - * qualified name of a constant {@link java.sql2.SqlType}, - * for example an enum that implements that interface. - * - * @return the name of the SQL type of the value bound to the parameter - */ - public String sqlType() default ""; -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlRef.java --- a/src/java.sql/share/classes/java/sql2/SqlRef.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.util.concurrent.CompletionStage; - -/** - * - * @param - */ -public interface SqlRef { - - /** - * Return the name of SQL type of the referent of this SQL REF. - * - * ISSUE: Oracle Database JDBC driver may do a round trip for this. Is this - * that heavy in other databases? - * - * @return - */ - public String getReferentTypeName(); - - /** - * Create and return an Operation that will fetch the value of the REF from - * the database. The value of the Operation is the value of the REF. - * - * @return an Operation that will fetch the referent of this SqlRef - */ - public Operation fetchOperation(); - - /** - * Submit an Operation that will fetch the value of the REF in the database. - * - * @return a Future that will complete when the submitted Operation completes. - * The value of the Future is the value of the REF. - */ - public default CompletionStage fetch() { - return fetchOperation().submit().getCompletionStage(); - } - - /** - * Create and return an Operation that will set the value of the REF in the - * database. - * - * @param value - * @return an Operation that will store the new referent into the REF - */ - public Operation storeOperation(T value); - - /** - * Submit an Operation that will store the new value of the referent into - * the REF in the database. - * - * @param value - * @return a Future that will complete when the submitted Operation completes. - */ - public default CompletionStage store(T value) { - return storeOperation(value).submit().getCompletionStage(); - } -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlSkippedException.java --- a/src/java.sql/share/classes/java/sql2/SqlSkippedException.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -/** - * A {@link SqlException} that is used to complete an {@link Operation} when that {@link Operation} is - * skipped. If an {@link Operation} is skipped the {@link Operation} is removed from the head of - * the queue, no work is sent to the database and the {@link java.util.concurrent.CompletionStage} of that - * {@link Operation} is completed exceptionally with a {@link SqlSkippedException}. The cause of - * the {@link SqlSkippedException} is the {@link Throwable} that caused the {@link Operation} to be - * skipped, if any. - * - */ -public class SqlSkippedException extends SqlException { - - /** - * - * @param message - * @param cause - * @param sqlState - * @param vendorCode - * @param sql - * @param position - */ - public SqlSkippedException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) { - super(message, cause, sqlState, vendorCode, sql, position); - } -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlStruct.java --- a/src/java.sql/share/classes/java/sql2/SqlStruct.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.TYPE; -import java.lang.annotation.Retention; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Identifies a type that represents a STRUCT SQL type. - */ -@Target({TYPE}) -@Retention(RUNTIME) -public @interface SqlStruct { - - /** - * The SQL name of the SQL STRUCT type. - * - * @return the SQL identifier - */ - public String sqlTypeName(); - - /** - * The fields of the SQL STRUCT type. - * - * @return the fields - */ - public Field[] fields(); - - /** - * Describes a field of a SQL STRUCT type. - */ - public @interface Field { - - /** - * The name of the field in the SQL STRUCT. - * - * @return the name of the field - */ - public String sqlFieldName(); - - /** - * The name of the SQL type of the field - * - * @return the SQL type name of the field - */ - public String sqlTypeName(); - - /** - * The Java identifier corresponding to the SQL field. This identifier is - * used to determine the corresponding getter and setter for getting and - * setting the value of this field in the annotated Java type. - * - * Implementations may choose to directly access a field named with the same - * identifier or a constructor or static factory method where all of the - * formal parameters are named by @Field annotations in the applied - * @SqlStruct. - * - * @return a Java identifier - */ - public String javaFieldName(); - } -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/SqlType.java --- a/src/java.sql/share/classes/java/sql2/SqlType.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -/** - * Remove dependence on java.sql. - */ -public interface SqlType { - - /** - * - * @return - */ - public String getName(); - - /** - * - * @return - */ - public String getVendor(); - - /** - * - * @return - */ - public Integer getVendorTypeNumber(); -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/StaticMultiOperation.java --- a/src/java.sql/share/classes/java/sql2/StaticMultiOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * A multi-operation is an {@link Operation} that returns one or more results in - * addition to the result defined by the {@link Operation}. A - * {@link StaticMultiOperation} is a multi-operation where the number and types - * of the results are known in advance. Operations are executed in the order - * submitted. If an {@link Operation} is created but not submitted prior to the - * {@link StaticMultiOperation} being submitted, submitting the - * {@link StaticMultiOperation} throws {@link IllegalStateException}. - * - * @param The type of the result of this {@link Operation} - * @see DynamicMultiOperation - * @author douglas.surber - */ -public interface StaticMultiOperation extends OutOperation { - - /** - * Returns a {@link RowOperation} to process a row sequence result. The - * {@link Operation}s are executed in the order they are submitted. If a - * result is of the wrong type for the next submitted {@link Operation} the - * {@link StaticMultiOperation} is completed with - * {@link IllegalStateException}. - * - * @return a {@link RowOperation} that is part of this {@link StaticMultiOperation} - */ - public RowOperation rowOperation(); - - /** - * Returns a {@link CountOperation} to process a count result. The {@link Operation}s - * are executed in the order they are submitted. If a result is of the wrong - * type for the next submitted Operation the {@link StaticMultiOperation} is completed - * with {@link IllegalStateException}. - * - * @return a {@link CountOperation} that is part of this {@link StaticMultiOperation} - */ - public CountOperation countOperation(); - - // Covariant overrides - - @Override - public StaticMultiOperation onError(Consumer handler); - - @Override - public StaticMultiOperation apply(Function processor); - - @Override - public StaticMultiOperation outParameter(String id, SqlType type); - - @Override - public StaticMultiOperation set(String id, Object value, SqlType type); - - @Override - public StaticMultiOperation set(String id, Object value); - - @Override - public StaticMultiOperation set(String id, CompletionStage source, SqlType type); - - @Override - public StaticMultiOperation set(String id, CompletionStage source); - - @Override - public StaticMultiOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/Submission.java --- a/src/java.sql/share/classes/java/sql2/Submission.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Future; - -/** - * The result of submitting an {@link Operation}. The {@link cancel} method of a - * {@link CompletionStage} does not cancel the {@link Operation}. This is part - * of the contract of {@link CompletionStage}. This type provides a method to - * cancel the {@link Operation}. Canceling an {@link Operation} only makes sense - * after the {@link Operation} is submitted so this type is the result of - * submitting an {@link Operation}. - * - * ISSUE: Should Operation.submit return a CompletionStage with the requirement - * that cancel attempts to cancel the database action? Conceptually this is fine. - * The concern is that it requires the implementor to implement their own - * CompletionStage or at the least subclass CompletableFuture to override - * cancel. Neither of these is trivial. - * - * @param The type of the result of the {@link Operation} that created this - * {@link Submission} - */ -public interface Submission { - - /** - * Request that the {@link Operation} not be executed or that its execution be - * aborted if already begun. This is a best effort action and may not succeed - * in preventing or aborting the execution. This method does not block. - * - * If execution is prevented the Operation is completed exceptionally with - * SkippedSqlException. If the Operation is aborted it is completed - * exceptionally with SqlException. - * - * @return a {@link java.util.concurrent.Future} that is true if the - * {@link Operation} is canceled. - */ - public Future cancel(); - - /** - * Returns a {@link CompletionStage} which value is the result of the - * {@link Operation}. Any actions on the returned {@link CompletionStage}, - * eg {@code completeExceptionally} or {@code cancel}, have no impact on this - * {@link Operation}. If this {@link Operation} is already completed the - * returned {@link CompletionStage} will be completed. - * - * The returned {@link CompletionStage} is completed after the Operation - * is completed. It may be completed by the same thread that completed the - * Operation or a different one. The Operation following the one that created - * this Submission begins execution when the Operation that created this - * Submission is completed. It is not required to wait for the returned - * CompletionStage to complete. [Note: this is necessary because the app can - * call this method after the Operation completes.] - * - * Each call of this method for a given {@link Operation} returns the same - * {@link CompletionStage}. - * - * @return the {@link java.util.concurrent.CompletionStage} for the result of this - * {@link Operation}. Retained. - */ - public CompletionStage getCompletionStage(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/Transaction.java --- a/src/java.sql/share/classes/java/sql2/Transaction.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -/** - * A mutable object that controls whether a transactionEnd Operation sends - * a database commit or a database rollback to the server. A transactionEnd - * Operation is created with a Transaction. By default a transactionEnd - * Operation requests that the database end the transaction with a commit. - * If Transaction#setRollbackOnly is called on the Transaction used to create - * the Operation prior to the Operation being executed, the Operation will - * request that the database end the transaction with a rollback. - * - * Example: - * - *
- * {@code
- *   Transaction t = conn.transaction();
- *   conn.countOperation(updateSql)
- *       .resultProcessor( count -> { if (count > 1) t.setRollbackOnly(); } )
- *       .submit();
- *   conn.commit(t);
- * }
- * - * A Transaction can not be used to create more than one endTransaction - * Operation. - * - * A Transaction is thread safe. - */ -public interface Transaction { - - /** - * Causes an endTransactionOperation created with this Transaction that is executed - * subsequent to this call to perform a rollback. If this method is not called - * prior to Operation execution the Operation will perform a commit. - * - * @return true if the call succeeded. False if the call did not succeed in - * setting the Transaction rollback only because the endTransaction - * Operation had already been executed. - */ - public boolean setRollbackOnly(); - - /** - * Returns {@code true} iff the {@link setRollbackOnly} method has been called - * on this Transaction - * - * @return {@code true} if {@link setRollbackOnly} has been called. - */ - public boolean isRollbackOnly(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/TransactionOutcome.java --- a/src/java.sql/share/classes/java/sql2/TransactionOutcome.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -/** - * Possible outcomes for a database transaction. - */ -public enum TransactionOutcome { - /** - * The outcome of the transaction is unknown. - */ - UNKNOWN, - - /** - * The transaction committed successfully. - */ - COMMIT, - - /** - * The transaction rolled back successfully. - */ - ROLLBACK; -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/package-info.java --- a/src/java.sql/share/classes/java/sql2/package-info.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,435 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -/** - *

- * An API for accessing and processing data stored in a data source (usually a - * relational database) using the Java™ programming language. This API - * includes a framework whereby different drivers can be installed dynamically - * to access different data sources. This API is specifically geared for passing - * SQL statements to a database though it may be used for reading and writing - * data from/to any data source that has a tabular format.

- * - *

- * This API differs from the API in {@link java.sql} in several ways.

- *
    - *
  • Is asynchronous - *
  • Is geared toward high-throughput programs - *
  • Does not attempt to support every database feature - *
  • Does not attempt to abstract the database - *
  • Uses the builder pattern - *
  • Supports the fluent programming style - *
- * - *

- * It is worth emphasizing that this API is an alternate to the {@link java.sql} - * API, not a replacement. There are many programs that can much more readily be - * written using the {@link java.sql} API as it has many features that are not - * available in this API. For example this API provides almost no mechanism for - * getting metadata.

- * - *

- * This API is not an extension to the {@link java.sql} API. It an independent - * API and is used on its own without reference to java.sql.

- * - * - *

Overview

- * - *

- * The core feature of this API is that it is asynchronous. No method call will - * wait for a network operation.

- * - *

- * Possibly blocking actions are represented as {@link Operation}s. An - * application using the API creates and submits one or more {@link Operation}s. - * The driver executes these {@link Operation}s asynchronously, reporting their - * results via {@link java.util.concurrent.CompletionStage}s. An application - * can respond to the results via the - * {@link java.util.concurrent.CompletionStage}s or via callbacks that can be - * configured on many of the {@link Operation}s or both. Creating and submitting - * {@link Operation}s is strictly non-blocking. Handling the results of possibly - * blocking {@link Operation}s is done asynchronously. No application thread - * will ever block on a call to a method in this API.

- * - *

- * All {@link Operation}s provide a - * {@link java.util.concurrent.CompletionStage}. The value of that - * {@link java.util.concurrent.CompletionStage} is the value of the - * {@link Operation}, set when the {@link Operation} completes. Some - * {@link Operation}s provide callbacks for processing the result of the - * {@link Operation} independent of the - * {@link java.util.concurrent.CompletionStage}. Those {@link Operation}s can - * be used for executing SQL that returns results of a specific type. For - * example SQL that returns a row sequence would be executed with a - * {@link RowOperation}. A {@link RowOperation} provides callbacks for - * processing each row and for collecting the results of processing the rows. - * Other {@link Operation}s are specialized for SQL that returns a count or that - * returns out parameters. The choice of {@link Operation} is dependent on the - * result to be processed and is independent of the particular kind of SQL - * statement.

- * - *

- * An {@link OperationGroup} encapsulates a group of {@link Operation}s and - * executes them using common attributes. An {@link OperationGroup} can be - * unconditional or conditional, sequential or parallel, dependent or - * independent, or any combination of these. Dependent/independent controls - * error handling. If one member of a dependent {@link OperationGroup} fails the - * remaining not-yet-executed members are completed exceptionally. If the - * {@link OperationGroup} is independent, the member {@link Operation}s are - * executed regardless of whether one or more fails.

- * - *

- * A {@link Connection} is itself an {@link OperationGroup} and so can be - * conditional, parallel, or independent, but by default is unconditional, - * sequential, dependent. While a {@link Connection} may be created with values - * other than the defaults, using the defaults is by far the most common case. - * The API provides convenience methods that support this case. Using these - * convenience methods is recommended in all but the most unusual circumstances. - * In particular making the {@link Connection} parallel introduces some - * challenges that would require a full understanding of the details of the API. - * It would almost certainly be better to create a parallel - * {@link OperationGroup} within the {@link Connection}.

- * - *

- * - * ISSUE: Should we disallow {@code Connection.parallel()}?

- * - *

- * The {@link java.sql} API frequently provides many ways to do the same thing. - * This API makes no attempt to do this. For those capabilities this API - * supports, it frequently defines exactly one way to do something. Doing things - * another way, for example calling methods in a non-standard order, frequently - * results in an IllegalStateException. This approach is intended to make things - * simpler for both the user and the implementor. Rather than having to - * understand complicated interactions of many different components and methods - * executed in any order, the intent is that there is only one way to do things - * so only one path must be understood or implemented. Anything off that path is - * an error. While this requires a programmer to write code in one specific way - * it makes things easier on future maintainers of the code as the code will - * conform to the standard pattern. Similarly the implementation is simplified - * as only the standard use pattern is supported.

- * - *

- * One way this API simplifies things in to define types as single use. Many - * types are created, configured, used once, and are then no longer usable. Many - * configuration methods can be called only once on a given instance. Once an - * instance is configured it cannot be reconfigured. Once an instance is used it - * cannot be reused. This simplifies things by eliminating the need to - * understand and implement arbitrary sequences of method calls that reconfigure - * and reuse instances. Since objects are single use there is no expectation - * that an application cache or share {@link Operation}s.

- * - *

- * While the user visible types are single use, it is expected that an - * implementation will cache and reuse data and {@link Object}s that are worth - * the effort. Rather than attempt to guess what an implementation should reuse - * and capture that in the API, this API leaves it entirely up to the - * implementation. Since the API specifies very little reuse, an implementation - * is free to reuse whatever is appropriate. Since the pattern of use is - * strictly enforced figuring out how to reuse objects is greatly - * simplified.

- * - *

- * The {@link java.sql} API provides many tools for abstracting the database, - * for enabling the user to write database independent code. This API does not. - * It is not a goal of this API to enable users to write database independent - * code. That is not to say it is not possible, just that this API does not - * provide tools to support such. Abstraction features typically impose - * performance penalties on some implementations. As this API is geared for - * high-throughput programs it avoids such abstractions rather than reduce - * performance.

- * - *

- * One such abstraction feature is the JDBC escape sequences. Implementing these - * features requires parsing the SQL so as to identify the escape sequences and - * then generating a new String with the vendor specific SQL corresponding to - * the escape sequence. This is an expensive operation. Further each SQL must be - * parsed whether it contains an escape sequence or not imposing the cost on all - * JDBC users, not just the ones who use escape sequences. The same is true of - * JDBC parameter markers. The SQL accepted by this API is entirely vendor - * specific, including parameter markers. There is no need for pre-processing - * prior to SQL execution substantially reducing the amount of work the - * implementation must do.

- * - *

- * Note: It would be a reasonable future project to develop a SQL builder API - * that creates vendor specific SQL from some more abstract representation.

- * - *

Execution Model

- * - *

- * This section describes the function of a conforming implementation. It is - * not necessary for an implementation to be implemented as described only that - * the behavior be the same.

- * - *

- * An {@link Operation} has an action and a - * {@link java.util.concurrent.CompletionStage}. Some {@link Operation}s have - * some form of result processor.

- * - *

- * An {@link Operation} is executed by causing the action to be performed, - * processing the result of the action if there is a result processor, and - * completing the {@link java.util.concurrent.CompletionStage} with the result - * of the result processor if there is one or with the result of the action if - * there is no result processor. If the action or the result processing causes - * an unhandled error the {@link java.util.concurrent.CompletionStage} is - * completed exceptionally. The CompletionStage is completed asynchronously, - * as though it were created by calling an async method on - * CompletionStage. - *

- * - *

- * Performing the action may require one or more interactions with the database. - * These interactions may be carried out in parallel with processing the result. - * If the database result is ordered, that result is processed in that order. - * - *

- * An {@link OperationGroup} has a collection of {@link Operation}s and - * optionally a condition. For a sequential {@link OperationGroup} - * {@link Operation}s are selected from the collection in the order they were - * submitted. For a parallel {@link OperationGroup} {@link Operation}s are - * selected from the collection in any order.

- * - *

- * The action of an {@link OperationGroup} is performed as follows: - *

    - *
  • - * If the {@link OperationGroup} has a condition, the value of the condition is - * retrieved. If the value is {@link Boolean#FALSE} the action is complete and - * the {@link java.util.concurrent.CompletionStage} is completed with null. If - * the value completes exceptionally the action is complete and the - * {@link java.util.concurrent.CompletionStage} is completed exceptionally - * with the same exception. If the condition value is {@link Boolean#TRUE} or - * there is no condition the {@link Operation}s in the collection are executed - * and their results processed. The action is complete when the - * {@link OperationGroup} is not held and all the {@link Operation}s have been - * executed.
  • - *
  • - * If the {@link OperationGroup} is parallel more than one {@link Operation} may - * be executed at a time.
  • - *
  • - * If the {@link OperationGroup} is dependent and an {@link Operation} completes - * exceptionally all {@link Operation}s in the collection that are yet to begin - * execution are completed exceptionally with a {@link SqlSkippedException}. The - * cause of that exception is the {@link Throwable} that caused the - * {@link Operation} to be completed exceptionally. If an {@link Operation} is - * in flight when another {@link Operation} completes exceptionally the in - * flight {@link Operation} may either be allowed to complete uninterrupted or - * it may be completed exceptionally. The {@link OperationGroup} is completed - * exceptionally with the {@link Throwable} that caused the {@link Operation} to - * complete exceptionally. Note: the {@link Operation} returned by - * {@link Connection#closeOperation} is never skipped, i.e. never completed - * exceptionally with {@link SqlSkippedException}. It is always executed.
  • - *
  • - * If the {@link OperationGroup} is independent and an {@link Operation} - * completes exceptionally all other {@link Operation}s are executed regardless. - * There is no result to be processed for an {@link Operation} that completed - * exceptionally. The {@link OperationGroup} is not completed exceptionally as - * the result of one or more {@link Operation}s completing exceptionally.
  • - *
- * - *

- * A {@link Connection} is a distinguished {@link OperationGroup}. A - * {@link Connection} is executed upon being submitted.

- * - *

Transactions

- * - *

- * This section describes the function of a conforming implementation. It is - * not necessary for an implementation to be implemented as described only that - * the behavior be the same.

- * - *

- * An implementation has only limited control over transactions. SQL statements - * can start, commit, and rollback transactions without the implementation - * having any influence or even being aware. This specification only describes - * the behavior of those transaction actions that are visible to and controlled - * by the implementation, i.e. the endTransaction {@link Operation}. - * Transaction actions caused by SQL may interact with actions controlled by the - * implementation in unexpected ways.

- * - *

- * The creation of Operations and the subsequent execution of those Operations - * are separated in time. It is quite reasonable to determine that a transaction - * should commit after the Operation that ends the transaction is created. - * But if the execution of the transaction does not result in the expected results - * it might be necessary to rollback the transaction rather than commit it. This - * determination depends on the execution of the Operations long after the - * endTransaction Operation is created. To address this mismatch, the endTransaction Operation - * specified by this API is conditioned by a {@link Transaction}. It commits the - * transaction by default, a {@link Transaction} will cause an endTransaciton - * {@link Operation} to commit the transaction but a Transaction can be set - * to rollback the transaction at any time before the endTransaction - * {@link Operation} that references it is executed.

- * - *

- * An endTransaction Operation, like all Operations, is immutable once submitted. - * But an endTransaction Operation is created with a Transaction and that - * Transaction can be set to commit or rollback. A Transaction controls the - * endTransaction Operation created with it. Using this mechanism an - * error handler, result handler or other code can cause a subsequent endTransaction - * Operation to rollback instead of the default which is to commit.

- * - *
- * {@code
- *   Transaction t = conn.getTransaction();
- *   conn.countOperation(updateSql)
- *       .resultProcessor( count -> { 
- *           if (count > 1) t.setRollbackOnly(); 
- *           return null; 
- *       } )
- *       .submit();
- *   conn.commitMaybeRollback(t);
- * }
- * 
- * - *

- * In this example if the update SQL modifies more than one row the result - * processor will set the Transaction to rollback only. When the endTransaction - * Operation submitted by commitMaybeRollback is executed it will cause - * the transaction to rollback.

- * - * - *

POJOs

- * - *

Does this feature carry its weight? It is a nice ease of use feature - * for hand written code but it is not of much valuable for framework code. It - * certainly is not strictly necessary. Arguably it should be removed.

- * - *

- * This API supports setting and getting POJOs (Plain Old Java Objects) as - * parameter values and results. This is not a comprehensive ORM (Object - * Relational Mapping). It is just a convenience. - * - *

- * To set parameters of a SQL statement to the values of a POJO, the type of the - * POJO must be annotated with the @SqlParameter annotation. One or more public - * getter methods must be so annotated. The @SqlParameter annotation defines the - * parameter marker base name and SQL type. The call to the - * ParameterizedOperation.set method provides the POJO itself and the parameter - * marker prefix. The implementation binds the return value of the annotated - * method to the parameter identified by the parameter marker prefix prepended - * to the parameter marker base name.

- * - *
- * {@code
- *   public class Employee {
- *     private String name;
- *     private String department;
- *     \@SqlParameter("name", "VARCHAR")
- *     public String getName() { return name; }
- *     public String getDepartement() { return department; }
- *     \@SqlColumns("name", "dept")
- *     public static Employee createEmployee(String name, String department) {
- *       Employee e = new Employee();
- *       e.name = name;
- *       e.department = department;
- *       return e;
- *     }
- *   }
- *
- *   conn.countOperation("insert into emp values(:emp_name, :emp_dept)")
- *       .set("emp_", employee);
- * }
- * 
- * - *

- * The above code fragment is identical to

- * - *
- * {@code
- *    conn.countOperation("insert into emp values(emp_name, emp_dept)")
- *       .set("emp_name", employee.getName(), JdbcType.VARCHAR);
- *       .set("emp_dept", employee.getDepartment(), JdbcType.VARCHAR)
- * }
- * 
- * - *

- * The prefix may be the empty string but may not be null. IllegalStateException - * is thrown if a parameter is set more than once either by a POJO set or a - * single value set. Implementations may attempt to bind a parameter for every - * annotated getter method. An implementation is not required to check whether - * or not there is a parameter with the specified name. It is implementation - * dependent whether an annotated getter with no corresponding parameter is an - * error or not and whether the implementation or the database detect it if it - * is an error.

- * - *

- * To construct a POJO from the result of an Operation the type of the POJO must - * be annotated with @SqlColumns. The annotation may be applied to a public - * static factory method, a public constructor, or one or more public setter - * methods. If applied to setters, there must be a public zero-arg constructor - * or public static zero-arg factory method. The annotation provides the base - * names for column or out parameter marker that provides the value for the - * corresponding parameter or setter method. The get method call provides the - * prefix.

- * - *
- * {@code
- *     conn.rowOperation("select name, dept from emp")
- *     .collect(Collector.of(
- *         () -> new ArrayList(),
- *         (l, r) -> { 
- *             l.add(r.get("", Employee.class)); 
- *         }
- *         (l, r) -> l
- *     ) )
- * }
- * 
- * - *

- * The above code fragment is identical to

- * - *
- * {@code
- *     conn.rowOperation("select name, dept from emp")
- *     .collect(Collector.of(
- *         () -> new ArrayList(),
- *         (l, r) -> { 
- *             l.add(Employee.createEmployee(r.get("name", String.class), 
- *                                         r.get("dept", String.class))); 
- *         }
- *         (l, r) -> l
- *     ) )
- * }
- * 
- * - *

- * If more than one factory method, constructor, or set of setters is annotated - * it is implementation dependent which is used to construct a POJO. An - * implementation is not required to determine the best choice for any meaning - * of "best". An implementation my instead throw an exception if more than one - * alternative is annotated. If setters are annotated an implementation should - * call every annotated setter. It is implementation dependent whether it - * attempts to call a subset of the setters if all the columns named in the - * annotations are not present. In summary, best practice is to annotate exactly - * what is required and no more and to use exactly what is annotated and no more. - *

- * - */ -package java.sql2; - diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaConnectionProperty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaConnectionProperty.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.util.function.Function; +import java.time.Duration; +import java.util.concurrent.Executor; +import java.util.concurrent.ForkJoinPool; + +/** + * A set of {@link ConnectionProperty} commonly supported. Implementations are not + * required to support all of these properties. + * + */ +public enum AdbaConnectionProperty implements ConnectionProperty { + + /** + * + */ + CACHING(Caching.class, + v -> v instanceof Caching, + Caching.CACHED, + false), + + /** + * + */ + EXECUTOR(Executor.class, + v -> v instanceof Executor, + ForkJoinPool.commonPool(), + false), + + /** + * + */ + CONNECT_TIMEOUT(Duration.class, + v -> v instanceof Duration && ! ((Duration)v).isNegative(), + Duration.ofSeconds(Long.MAX_VALUE), + false), + + /** + * + */ + HOLDABILITY(Holdability.class, + v -> v instanceof Holdability, + Holdability.HOLD_OVER_COMMIT, + false), + + /** + * + */ + NETWORK_TIMEOUT(Integer.class, + v -> v instanceof Integer && ((int) v) >= 0, + Integer.MAX_VALUE, + false), + + /** + * + */ + PASSWORD(String.class, + v -> v instanceof String, + null, + true), + + /** + * + */ + READ_ONLY(Boolean.class, + v -> v instanceof Boolean, + false, + false), + + /** + * + */ + SHARDING_KEY(ShardingKey.class, + v -> v instanceof ShardingKey, + null, + false), + + /** + * + */ + SHARDING_GROUP_KEY(ShardingKey.class, + v -> v instanceof ShardingKey, + null, + false), + + /** + * + */ + TRANSACTION_ISOLATION(TransactionIsolation.class, + v -> v instanceof TransactionIsolation, + TransactionIsolation.READ_COMMITTED, + false), + + /** + * + */ + URL(String.class, + v -> v instanceof String, + null, + false), + + /** + * + */ + USER(String.class, + v -> v instanceof String, + null, + false); + + private final Class range; + private final Function validator; + private final Object defaultValue; + private final boolean isSensitive; + + private AdbaConnectionProperty(Class range, + Function validator, + Object value, + boolean isSensitive) { + this.range = range; + this.validator = validator; + this.defaultValue = value; + this.isSensitive = isSensitive; + } + + @Override + public Class range() { + return range; + } + + @Override + public boolean validate(Object value) { + return validator.apply(value); + } + + @Override + public Object defaultValue() { + return defaultValue; + } + + @Override + public boolean isSensitive() { + return isSensitive; + } + + /** + * + */ + public enum Caching { + /** + * The returned {@link Connection} is required to be completely new and configured + * exactly as specified by the other properties. Use this with caution and + * only when absolutely necessary. Use {@link AS_NEW} instead if at all possible. + * This should be used only to work around some limitation of the database + * or the implementation. + */ + NEW, + /** + * The returned {@link Connection} has no state other than that of a new Connection + * modified as specified by the other properties. May not be strictly new + * but has the same behavior as a new {@link Connection}. The {@link Connection} may be {@link NEW}. The default. + */ + AS_NEW, + /** + * The returned {@link Connection} has the state specified by the other properties + * but may have additional state that differs from that of a new {@link Connection}. + * The {@link Connection} may be {@link AS_NEW}. + */ + CACHED; + } + + /** + * + */ + public enum TransactionIsolation { + + /** + * + */ + NONE, + + /** + * + */ + READ_COMMITTED, + + /** + * + */ + READ_UNCOMMITTED, + + /** + * + */ + REPEATABLE_READ, + + /** + * + */ + SERIALIZABLE; + } + + /** + * + */ + public enum Holdability { + + /** + * + */ + HOLD_OVER_COMMIT, + + /** + * + */ + CLOSE_AT_COMMIT; + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * Remove dependence on java.sql. + */ +public enum AdbaType implements SqlType { + + /** + * + */ + ARRAY, + + /** + * + */ + BIGINT, + + /** + * + */ + BINARY, + + /** + * + */ + BIT, + + /** + * + */ + BOOLEAN, + + /** + * + */ + CHAR, + + /** + * + */ + CLOB, + + /** + * + */ + CURSOR, + + /** + * + */ + DATALINK, + + /** + * + */ + DATE, + + /** + * + */ + DECIMAL, + + /** + * + */ + DISTINCT, + + /** + * + */ + DOUBLE, + + /** + * + */ + FLOAT, + + /** + * + */ + INTEGER, + + /** + * + */ + JAVA_OBJECT, + + /** + * + */ + LONGNVARCHAR, + + /** + * + */ + LONGVARBINARY, + + /** + * + */ + LONGVARCHAR, + + /** + * + */ + NCHAR, + + /** + * + */ + NCLOB, + + /** + * + */ + NULL, + + /** + * + */ + NUMERIC, + + /** + * + */ + NVARCHAR, + + /** + * + */ + OTHER, + + /** + * + */ + REAL, + + /** + * + */ + REF, + + /** + * + */ + REF_CURSOR, + + /** + * + */ + ROWID, + + /** + * + */ + SMALLINT, + + /** + * + */ + SQLXML, + + /** + * + */ + STRUCT, + + /** + * + */ + TIME, + + /** + * + */ + TIMESTAMP, + + /** + * + */ + TIME_WITH_TIME_ZONE, + + /** + * + */ + TIMESTAMP_WITH_TIME_ZONE, + + /** + * + */ + TINYINT, + + /** + * + */ + VARBINARY, + + /** + * + */ + VARCHAR; + + /** + * + * @return + */ + @Override + public String getName() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * + * @return + */ + @Override + public String getVendor() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * + * @return + */ + @Override + public Integer getVendorTypeNumber() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType_1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType_1.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * Remove dependence on java.sql. + */ +public enum AdbaType_1 implements SqlType { + + /** + * + */ + ARRAY, + + /** + * + */ + BIGINT, + + /** + * + */ + BINARY, + + /** + * + */ + BIT, + + /** + * + */ + BOOLEAN, + + /** + * + */ + CHAR, + + /** + * + */ + CLOB, + + /** + * + */ + CURSOR, + + /** + * + */ + DATALINK, + + /** + * + */ + DATE, + + /** + * + */ + DECIMAL, + + /** + * + */ + DISTINCT, + + /** + * + */ + DOUBLE, + + /** + * + */ + FLOAT, + + /** + * + */ + INTEGER, + + /** + * + */ + JAVA_OBJECT, + + /** + * + */ + LONGNVARCHAR, + + /** + * + */ + LONGVARBINARY, + + /** + * + */ + LONGVARCHAR, + + /** + * + */ + NCHAR, + + /** + * + */ + NCLOB, + + /** + * + */ + NULL, + + /** + * + */ + NUMERIC, + + /** + * + */ + NVARCHAR, + + /** + * + */ + OTHER, + + /** + * + */ + REAL, + + /** + * + */ + REF, + + /** + * + */ + REF_CURSOR, + + /** + * + */ + ROWID, + + /** + * + */ + SMALLINT, + + /** + * + */ + SQLXML, + + /** + * + */ + STRUCT, + + /** + * + */ + TIME, + + /** + * + */ + TIMESTAMP, + + /** + * + */ + TIME_WITH_TIME_ZONE, + + /** + * + */ + TIMESTAMP_WITH_TIME_ZONE, + + /** + * + */ + TINYINT, + + /** + * + */ + VARBINARY, + + /** + * + */ + VARCHAR; + + /** + * + * @return + */ + @Override + public String getName() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * + * @return + */ + @Override + public String getVendor() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * + * @return + */ + @Override + public Integer getVendorTypeNumber() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayCountOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayCountOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.List; +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.stream.Collector; + +/** + * A database operation that returns a count that is executed multiple times + * with multiple sets of parameter values in one database operation. The + * parameters are submitted to the database in the same order as in the + * sequences passed to the set methods. The count results are passed to the + * collector in the same order they are produced by the database. The + * value of the Operation is the final result produced by the collector. + * + * @param the type of the result of collecting the counts + */ +public interface ArrayCountOperation extends Operation { + + /** + * Set a sequence of parameter values. The value is captured and should not be + * modified before the {@link Operation} is completed. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values cannot be converted to the specified SQL type. + * + * @param id the identifier of the parameter marker to be set + * @param values the sequence of values the parameter is to be set to + * @param type the SQL type of the values to send to the database + * @return this Operation + * @throws IllegalArgumentException if the length of values is not the same as + * the length of the previously set parameter sequences or if the same id was + * passed in a previous call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, List values, SqlType type); + + /** + * Set a sequence of parameter values. Use a default SQL type determined by + * the type of the value argument. The value is captured and should not be + * modified before the {@link Operation} is completed. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values cannot be converted to the specified SQL type. + * + * @param id the identifier of the parameter marker to be set + * @param values the value the parameter is to be set to + * @return this {@link Operation} + * @throws IllegalArgumentException if the length of value is not the same as + * the length of the previously set parameter sequences or if the same id was + * passed in a previous call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, List values); + + /** + * Set a sequence of parameter values. The first parameter is captured and + * should not be modified before the {@link Operation} is completed. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values cannot be converted to the specified SQL type. + * + * @param the Java type of the individual parameter values + * @param id the identifier of the parameter marker to be set + * @param values the value the parameter is to be set to + * @param type the SQL type of the value to send to the database + * @return this Operation + * @throws IllegalArgumentException if the length of value is not the same as + * the length of the previously set parameter sequences or if the same id was + * passed in a previous call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, S[] values, SqlType type); + + /** + * Set a sequence of parameter values. Use a default SQL type determined by + * the type of the value argument. The parameter is captured and should not be + * modified before the {@link Operation} is completed. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values cannot be converted to the specified SQL type. + * + * @param the Java type of the individual parameter values + * @param id the identifier of the parameter marker to be set + * @param values the value the parameter is to be set to + * @return this Operation + * @throws IllegalArgumentException if the length of value is not the same as + * the length of the previously set parameter sequences or if the same id was + * passed in a previous call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, S[] values); + + /** + * Provide a source for a sequence of parameter values. + * + * This Operation is not executed until source is completed normally. If + * source completes exceptionally this Operation completes exceptionally with + * an IllegealArgumentException with the source's exception as the cause. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values of the source cannot be converted to the specified SQL type. + * + * If the length of the value of source is not the same as the length of all + * other parameter sequences this Operation is completed exceptionally with + * IllegalArgumentException. + * + * @param id the identifier of the parameter marker to be set + * @param source supplies the values the parameter is to be set to + * @param type the SQL type of the value to send to the database + * @return this Operation + * @throws IllegalArgumentException if the same id was passed in a previous + * call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, CompletionStage source, SqlType type); + + /** + * Provide a source for a sequence of parameter values. Use a default SQL type + * determined by the element type of the value of the source. + * + * This Operation is not executed until source is completed normally. If + * source completes exceptionally this Operation completes exceptionally with + * an IllegealArgumentException with the source's exception as the cause. + * + * The Operation is completed exceptionally with ClassCastException if any of + * the values of the source cannot be converted to the specified SQL type. + * + * If the length of the value of source is not the same as the length of all + * other parameter sequences this Operation is completed exceptionally with + * IllegalArgumentException. + * + * @param id the identifier of the parameter marker to be set + * @param source supplies the values the parameter is to be set to + * @return this {@link Operation} + * @throws IllegalArgumentException if the same id was passed in a previous + * call. + * @throws IllegalStateException if the {@link Operation} has been submitted + */ + public ArrayCountOperation set(String id, CompletionStage source); + + /** + * Provides a {@link Collector} to reduce the sequence of Counts.The result of + * the {@link Operation} is the result of calling finisher on the final + * accumulated result. If the {@link Collector} is + * {@link Collector.Characteristics#UNORDERED} counts may be accumulated out of + * order. If the {@link Collector} is + * {@link Collector.Characteristics#CONCURRENT} then the sequence of counts may be + * split into subsequences that are reduced separately and then combined. + * + * @param
the type of the accumulator + * @param the type of the final result + * @param c the Collector. Not null. + * @return This ArrayCountOperation + * @throws IllegalStateException if this method had been called previously or + * this Operation has been submitted. + */ + public ArrayCountOperation collect(Collector c); + + @Override + public Submission submit(); + + @Override + public ArrayCountOperation onError(Consumer handler); + + @Override + public ArrayCountOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Connection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Connection.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * A {@link Connection} is an abstraction of a connection to a SQL database and + * a group of {@link Operation}s to be executed by that SQL database. No method + * on {@link Connection} or any of its dependent objects ({@link RowOperation} + * etc) blocks with the exception of those few methods with "Wait" in their + * name. Any other method that might block must execute any potentially blocking + * action in a thread other than the calling thread. + * + * All methods inherited from OperationGroup throw IllegalStateException if the + * the connection is not active. + */ +public interface Connection extends AutoCloseable, OperationGroup { + + /** + * Identifies the operational state of a {@link Connection}. + */ + public enum Lifecycle { + /** + * unconnected. When a connect {@link Operation} is completed successfully + * -> {@link OPEN}. If {@link deactivate} is called -> + * {@link NEW_INACTIVE}. If {@link abort} is called -> {@link ABORTING}. + * No {@link Operation}s other than connect and close will be performed. A + * Connection in this state is both 'open' and 'active'. + */ + NEW, + /** + * Unconnected and inactive. Any queued connect or close {@link Operation} + * is performed. No work can be submitted. If the {@link activate} method is + * called -> {@link NEW}. If a connect {@link Operation} completes -> + * {@link INACTIVE}. If a close {@link Operation} is executed -> + * {@link CLOSING}. If {@link abort} is called -> {@link ABORTING}. A + * Connection in this state is 'open'. + */ + NEW_INACTIVE, + /** + * fully operational. Work is queued and performed. If {@link deactivate} is + * called -> {@link INACTIVE}. If a close {@link Operation} is executed + * -> {@link CLOSING}. If {@link abort} is called -> {@link ABORTING}. + * A Connection in this state is both 'open' and 'active'. + */ + OPEN, + /** + * Not available for new work. Queued work is performed. No work can be + * submitted. If the {@link activate} method is called -> {@link OPEN}. + * If a close {@link Operation} is executed -> {@link CLOSING}. If + * {@link abort} is called -> {@link ABORTING}. A {@link Connection} in + * this state is 'open'. + */ + INACTIVE, + /** + * Work in progress is completed but no additional work is started or + * queued. Attempting to queue work throws {@link IllegalStateException}. + * When the currently executing {@link Operation}s are completed -> + * {@link CLOSED}. All other queued Operations are completed exceptionally + * with SqlSkippedException. A Connection in this state is 'closed'. + */ + CLOSING, + /** + * Work is neither queued nor performed. The currently executing + * {@link Operation}s, if any, are terminated, exceptionally if necessary. + * Any queued {@link Operation}s are terminated exceptionally with + * {@link SqlSkippedException}. Attempting to queue work throws + * {@link IllegalStateException}. When the queue is empty -< + * {@link CLOSED}. A Connection in this state is 'closed'. + */ + ABORTING, + /** + * Work is neither queued nor performed. Attempting to queue work throws + * {@link IllegalStateException}. A Connection in this state is 'closed'. + */ + CLOSED; + + static { + NEW.init(true, true, NEW, NEW_INACTIVE, OPEN, ABORTING, CLOSING, CLOSED); + NEW_INACTIVE.init(true, false, NEW, NEW_INACTIVE, INACTIVE, ABORTING, CLOSING, CLOSED); + OPEN.init(true, true, OPEN, INACTIVE, OPEN, ABORTING, CLOSING, CLOSED); + INACTIVE.init(true, false, OPEN, INACTIVE, INACTIVE, ABORTING, INACTIVE, INACTIVE); + CLOSING.init(false, true, CLOSING, CLOSING, CLOSING, ABORTING, CLOSING, CLOSED); + ABORTING.init(false, true, ABORTING, ABORTING, ABORTING, ABORTING, ABORTING, CLOSED); + CLOSED.init(false, true, CLOSED, CLOSED, CLOSED, CLOSED, CLOSED, CLOSED); + } + + private boolean isOpen; + private boolean isActive; + private Lifecycle onActivate; + private Lifecycle onDeactivate; + private Lifecycle onConnect; + private Lifecycle onAbort; + private Lifecycle onClose; + private Lifecycle onClosed; + + private void init(boolean io, boolean ia, Lifecycle ac, Lifecycle da, Lifecycle cn, Lifecycle ab, Lifecycle cl, Lifecycle cd) { + isOpen = io; + isActive = ia; + onActivate = ac; + onDeactivate = da; + onConnect = cn; + onAbort = ab; + onClose = cl; + onClosed = cd; + } + public boolean isOpen() { + return isOpen; + } + + public boolean isActive() { + return isActive; + } + + public Lifecycle activate() { + return onActivate; + } + + public Lifecycle deactivate() { + return onDeactivate; + } + + public Lifecycle connect() { + return onConnect; + } + + public Lifecycle abort() { + return onAbort; + } + + public Lifecycle close() { + return onClose; + } + + public Lifecycle closed() { + return onClosed; + } + + } + + /** + * Specifiers for how much effort to put into validating a {@link Connection}. + * The amount of effort put into checking should be non-decreasing from NONE + * (least effort) to COMPLETE (most effort). Exactly what is checked is + * implementation dependent. For example, a memory resident database driver + * might implement SOCKET and NETWORK to be the same as LOCAL. SERVER might + * verify that a database manager thread is running and COMPLETE might trigger + * the database manager thread to run a deadlock detection algorithm. + */ + public enum Validation { + /** + * isValid fails only if the {@link Connection} is closed. + */ + NONE, + /** + * {@link NONE} plus check local resources + */ + LOCAL, + /** + * {@link LOCAL} plus the server isn't obviously unreachable (dead socket) + */ + SOCKET, + /** + * {@link SOCKET} plus the network is intact (network PING) + */ + NETWORK, + /** + * {@link NETWORK} plus significant server processes are running + */ + SERVER, + /** + * everything that can be checked is working. At least {@link SERVER}. + */ + COMPLETE; + } + + /** + * A Listener that is notified of changes in a Connection's lifecycle. + */ + public interface ConnectionLifecycleListener extends java.util.EventListener { + + /** + * If this {@link java.util.EventListener} is registered with a + * {@link Connection} this method is called whenever that + * {@link Connection}'s lifecycle changes. Note that the lifecycle may have + * changed again by the time this method is called so the + * {@link Connection}'s current lifecycle may be different from the value of + * {@code current}. + * + * @param conn the {@link Connection} + * @param previous the previous value of the lifecycle + * @param current the new value of the lifecycle + */ + public void lifecycleEvent(Connection conn, Lifecycle previous, Lifecycle current); + } + + /** + * A {@link Connection} builder. A {@link Connection} is initially in the + * {@link Connection.Lifecycle#NEW} lifecycle state. It transitions to the + * {@link Connection.Lifecycle#OPEN} lifecycle state when fully initialized or + * to {@link Connection.Lifecycle#CLOSED} if initialization fails. + * + */ + public interface Builder { + + /** + * Specify a property and its value for the built {@link Connection}. + * + * @param p {@link ConnectionProperty} to set. Not {@code null}. + * @param v value for the property + * @return this {@link Builder} + * @throws IllegalArgumentException if {@code p.validate(v)} does not return + * true or if this method has already been called with the property + * {@code p}. + */ + public Builder property(ConnectionProperty p, Object v); + + /** + * Return a {@link Connection} with the attributes specified. Note that the + * {@link Connection} may not be connected to a server. Call one of the + * {@link connect} convenience methods to connect the {@link Connection} to + * a server. The lifecycle of the new {@link Connection} is {@link Lifecycle#NEW}. + * + * @return a {@link Connection} + * @throws IllegalStateException if this method has already been called. + */ + public Connection build(); + } + + /** + * Returns an {@link Operation} that connects this {@link Connection} to a + * server. If the Operation completes successfully and the lifecycle is + * {@link Lifecycle#NEW} -> {@link Lifecycle#OPEN}. If lifecycle is + * {@link Lifecycle#NEW_INACTIVE} -> {@link Lifecycle#INACTIVE}. If the + * {@link Operation} completes exceptionally the lifecycle -> + * {@link Lifecycle#CLOSED}. The lifecycle must be {@link Lifecycle#NEW} or + * {@link Lifecycle#NEW_INACTIVE} when the {@link Operation} is executed. + * Otherwise the {@link Operation} will complete exceptionally with + * {@link SqlException}. + * + * Note: It is highly recommended to use the {@link connect()} convenience + * method or to use {@link DataSource#getConnection} which itself calls + * {@link connect()}. Unless there is a specific need, do not call this method + * directly. + * + * This method exists partially to clearly explain that while creating a + * {@link Connection} is non-blocking, the act of connecting to the server may + * block and so is executed asynchronously. We could write a bunch of text + * saying this but defining this method is more explicit. Given the + * {@link connect()} convenience methods there's probably not much reason to + * use this method, but on the other hand, who knows, so here it is. + * + * @return an {@link Operation} that connects this {@link Connection} to a + * server. + * @throws IllegalStateException if this {@link Connection} is in a lifecycle + * state other than {@link Lifecycle#NEW}. + */ + public Operation connectOperation(); + + /** + * Convenience method that supports the fluent style of the builder needed by + * try with resources. + * + * Note: A {@link Connection} is an {@link OperationGroup} and so has some + * advanced features that most users do not need. Management of these features + * is encapsulated in this method and the corresponding {@link close()} + * convenience method. The vast majority of users should just use these + * methods and not worry about the advanced features. The convenience methods + * do the right thing for the overwhelming majority of use cases. A tiny + * number of users might want to take advantage of the advanced features that + * {@link OperationGroup} brings to {@link Connection} and so would call + * {@link connectOperation} directly. + * + * @return this Connection + * @throws IllegalStateException if this {@link Connection} is in a lifecycle + * state other than {@link Lifecycle#NEW}. + */ + public default Connection connect() { + this.submitHoldingForMoreMembers(); + this.connectOperation() + .submit(); + return this; + } + + /** + * Convenience method that supports the fluent style of the builder needed by + * try with resources. + * + * @param onError an Exception handler that is called if the connect + * {@link Operation} completes exceptionally. + * @return this {@link Connection} + * @throws IllegalStateException if this {@link Connection} is in a lifecycle + * state other than {@link Lifecycle#NEW}. + */ + public default Connection connect(Consumer onError) { + this.submitHoldingForMoreMembers(); + this.connectOperation() + .submit() + .getCompletionStage() + .exceptionally(t -> { onError.accept(t); return null; } ); + return this; + } + + /** + * Returns an {@link Operation} that verifies that the resources are available + * and operational. Successful completion of that {@link Operation} implies + * that at some point between the beginning and end of the {@link Operation} + * the Connection was working properly to the extent specified by {@code depth}. + * There is no guarantee that the {@link Connection} is still working after + * completion. + * + * @param depth how completely to check that resources are available and + * operational. Not {@code null}. + * @return an {@link Operation} that will validate this {@link Connection} + * @throws IllegalStateException if this Connection is not active + */ + public Operation validationOperation(Validation depth); + + /** + * Convenience method to validate a {@link Connection}. + * + * @param depth how completely to check that resources are available and + * operational. Not {@code null}. + * @param minTime how long to wait. If 0, wait forever + * @param onError called if validation fails or times out. May be + * {@code null}. + * @return this {@link Connection} + * @throws IllegalArgumentException if {@code milliseconds} < 0 or + * {@code depth} is {@code null}. + * @throws IllegalStateException if this Connection is not active + */ + public default Connection validate(Validation depth, + Duration minTime, + Function onError) { + this.validationOperation(depth) + .timeout(minTime) + .submit() + .getCompletionStage() + .exceptionally(onError); + return this; + } + + /** + * Create an {@link Operation} to close this {@link Connection}. When the + * {@link Operation} is executed, if this {@link Connection} is open -> + * {@link Lifecycle#CLOSING}. If this {@link Connection} is closed executing + * the returned {@link Operation} is a no-op. When the queue is empty and all + * resources released -> {@link Lifecycle#CLOSED}. + * + * A close {@link Operation} is never skipped. Even when the + * {@link Connection} is dependent, the default, and an {@link Operation} + * completes exceptionally, a close {@link Operation} is still executed. If + * the {@link Connection} is parallel, a close {@link Operation} is not + * executed so long as there are other {@link Operation}s or the + * {@link Connection} is held; for more {@link Operation}s. + * + * Note: It is highly recommended to use try with resources or the + * {@link close()} convenience method. Unless there is a specific need, do not + * call this method directly. + * + * @return an {@link Operation} that will close this {@link Connection}. + * @throws IllegalStateException if the Connection is not active + */ + public Operation closeOperation(); + + /** + * Create and submit an {@link Operation} to close this {@link Connection}. + * Convenience method. + * + * Note: A {@link Connection} is an {@link OperationGroup} and so has some + * advanced features; that most users do not need. Management of these + * features is encapsulated in this method and the corresponding + * {@link connect()} convenience method. The vast majority of users should + * just use these methods and not worry about the advanced features. The + * convenience methods do the right thing for the overwhelming majority of use + * cases. A tiny number of user might want to take advantage of the advanced + * features that {@link OperationGroup} brings to {@link Connection} and so + * would call {@link closeOperation} directly. + * + * @throws IllegalStateException if the Connection is not active + */ + @Override + public default void close() { + this.closeOperation() + .submit(); + this.releaseProhibitingMoreMembers(); + } + + /** + * Create a new {@link OperationGroup} for this {@link Connection}. + * + * @param the result type of the member {@link Operation}s of the returned + * {@link OperationGroup} + * @param the result type of the collected results of the member + * {@link Operation}s + * @return a new {@link OperationGroup}. + * @throws IllegalStateException if this Connection is not active + */ + public OperationGroup operationGroup(); + + /** + * Returns a new {@link Transaction} that can be used as an argument to a + * commit Operation. + * + * It is most likely an error to call this within an error handler, or any + * handler as it is very likely that when the handler is executed the next + * submitted endTransaction {@link Operation} will have been created with a different + * Transaction. + * + * ISSUE: Should this be moved to OperationGroup? + * + * @return a new {@link Transaction}. Not retained. + * @throws IllegalStateException if this Connection is not active + */ + public Transaction transaction(); + + /** + * Convenience method that submits an endTransaction {@link Operation}. This + * {@link Operation} will always attempt to commit the transaction. + * When this method is used there is no way to cause the transaction to be ended + * with a rollback. + * + * @return this {@link Connection} + */ + public default CompletionStage commit() { + return this.commitMaybeRollback(transaction()); + } + + /** + * Create an endTransaction {@link Operation}, set it to rollback only, + * and submit it. Convenience method. + * + * @return this {@link OperationGroup} + */ + public default CompletionStage rollback() { + Transaction t = transaction(); + t.setRollbackOnly(); + return this.endTransactionOperation(t).submit().getCompletionStage(); + } + + /** + * Register a listener that will be called whenever there is a change in the + * lifecycle of this {@link Connection}.If the listener is already registered + this is a no-op. ISSUE: Should lifecycleListener be a ConnectionProperty so that it is + always reestablished on Connection.activate? + * + * @param listener Not {@code null}. + * @return this Connection + * @throws IllegalStateException if this Connection is not active + */ + public Connection registerLifecycleListener(ConnectionLifecycleListener listener); + + /** + * Removes a listener that was registered by calling + * registerLifecycleListener.Sometime after this method is called the listener + * will stop receiving lifecycle events. If the listener is not registered, + * this is a no-op. + * + * @param listener Not {@code null}. + * @return this Connection + * @throws IllegalStateException if this Connection is not active + */ + public Connection deregisterLifecycleListener(ConnectionLifecycleListener listener); + + /** + * Return the current lifecycle of this {@link Connection}. + * + * @return the current lifecycle of this {@link Connection}. + */ + public Lifecycle getConnectionLifecycle(); + + /** + * Terminate this {@link Connection}. If lifecycle is + * {@link Lifecycle#NEW}, {@link Lifecycle#OPEN}, {@link Lifecycle#INACTIVE} + * or {@link Lifecycle#CLOSING} -> {@link Lifecycle#ABORTING} If lifecycle + * is {@link Lifecycle#ABORTING} or {@link Lifecycle#CLOSED} this is a no-op. + * If an {@link Operation} is currently executing, terminate it immediately. + * Remove all remaining {@link Operation}s from the queue. {@link Operation}s + * are not skipped. They are just removed from the queue. + * + * @return this {@link Connection} + */ + public Connection abort(); + + /** + * Return the set of properties configured on this {@link Connection} + * excepting any sensitive properties. Neither the key nor the value for + * sensitive properties are included in the result. Properties (other than + * sensitive properties) that have default values are included even when not + * explicitly set. Properties that have no default value and are not set + * explicitly are not included. + * + * @return a {@link Map} of property, value. Not modifiable. May be retained. + * Not {@code null}. + * @throws IllegalStateException if this Connection is not active + */ + public Map getProperties(); + + /** + * + * @return a {@link ShardingKey.Builder} for this {@link Connection} + * @throws IllegalStateException if this Connection is not active + */ + public ShardingKey.Builder shardingKeyBuilder(); + + /** + * Make this {@link Connection} ready for use. A newly created + * {@link Connection} is active. Calling this method on a {@link Connection} + * that is active is a no-op. If the lifecycle is {@link Lifecycle#INACTIVE} + * -> {@link Lifecycle#OPEN}. If the lifecycle is + * {@link Lifecycle#NEW_INACTIVE} -> {@link Lifecycle#NEW}. + * + * @return this {@link Connection} + * @throws IllegalStateException if this {@link Connection} is closed. + */ + public Connection activate(); + + /** + * Makes this {@link Connection} inactive. After a call to this method + * previously submitted Operations will be executed normally. If the lifecycle + * is {@link Lifecycle#NEW} -> {@link Lifecycle#NEW_INACTIVE}. if the + * lifecycle is {@link Lifecycle#OPEN} -> {@link Lifecycle#INACTIVE}. If + * the lifecycle is {@link Lifecycle#INACTIVE} or + * {@link Lifecycle#NEW_INACTIVE} this method is a no-op. After calling this + * method or calling any method other than {@link deactivate}, {@link activate}, + * {@link abort}, or {@link getConnectionLifecycle} will throw + * {@link IllegalStateException}. Local {@link Connection} state not created + * by {@link Connection.Builder} may not be preserved. + * + * Any implementation of a {@link Connection} pool is by default required to + * call {@code deactivate} when putting a {@link Connection} into a pool. The + * implementation is required to call {@code activate} when removing a + * {@link Connection} from a pool so the {@link Connection} can be used. An + * implementation of a {@link Connection} pool may have an optional mode where + * it does not call {@code deactivate}/{@code activate} as required above. The + * behavior of the pool and {@link Connection}s cached in the pool in such a + * mode is entirely implementation dependent. + * + * @return this {@link Connection} + * @throws IllegalStateException if this {@link Connection} is closed + */ + public Connection deactivate(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ConnectionProperty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ConnectionProperty.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * An attribute of a {@link Connection} that can be configured to influence its + * behavior. Implementors of this interface define the properties of + * {@link Connection}s. The {@link Connection.Builder#property} method is used to set the values + * of {@link Connection} properties. + * + */ +public interface ConnectionProperty { + + /** + * Return the name of this {@link ConnectionProperty}. + * + * @return the name of this {@link ConnectionProperty} + */ + public String name(); + + /** + * Return the type of the value of this {@link ConnectionProperty}. Any value + * set for this property must be assignable to this type. + * + * @return the type of the values of this {@link ConnectionProperty} + */ + public Class range(); + + /** + * Determine whether a value is valid for this {@link ConnectionProperty}. Returns + * {@code true} if {@code value} is valid and {@code false} otherwise. + * + * @param value a value for this {@link ConnectionProperty} + * @return {@code true} iff {@code value} is valid for this {@link ConnectionProperty} + */ + public default boolean validate(Object value) { + return (value == null && this.range() == Void.class) || this.range().isInstance(value); + } + + /** + * Return the value for this property to use if no other value is set. For + * this to have any meaning for a user defined property the property must be + * registered with the {@link DataSource} by calling + * {@link DataSource.Builder#registerConnectionProperty}. + * + * @return the default value or {@code null} if there is no default value + */ + public Object defaultValue(); + + /** + * Returns true if this {@link ConnectionProperty} is contains sensitive information + * such as a password or encryption key. + * + * @return true iff this is sensitive + */ + public boolean isSensitive(); + + /** + * Returns an {@link Operation} that will configure the {@link Connection} to have the + * specified property value.May return {@code null} if no {@link Operation} needed. The + returned {@link Operation} is a member of group but is not submitted. + * + * Called by {@link Connection.Builder#build()} to configure a {@link Connection} as specified + * in the {@link Connection.Builder#property} method. ConnectionProperties known to the implementation + * may return {@code null} and rely on the implementation to do the right thing. + * + * @param + * @param group an {@link OperationGroup} which will be the container of the returned + * {@link Operation}, if any + * @param value the value to which the property is to be set. May be null if + * {@link range()} is {@link Void}. + * @return an {@link Operation} or null + * @throws IllegalStateException if it is not possible to configure the + * {@link Connection} as specified. + * @throws IllegalArgumentException if {@code this.validate(value)} returns {@code false} + */ + public default Operation configureOperation(OperationGroup group, Object value) { + if (validate(value)) { + return null; + } + else { + throw new IllegalArgumentException(value.toString() + " is invalid"); + } + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/CountOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/CountOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * An {@link Operation} that returns a count. + * + * @param the type of the result of the {@link Operation} + * @see ParameterizedCountOperation + */ +public interface CountOperation extends Operation { + + /** + * Sets the result processor for this {@link Operation}. + * + * @param function processes the count produced by executing this + * {@link Operation} and returns the result + * @return this {@link CountOperation} + * @throws IllegalStateException if this method has been called previously + */ + public CountOperation apply(Function function); + + @Override + public CountOperation onError(Consumer handler); + + @Override + public CountOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.util.LinkedList; +import java.util.List; +import java.util.function.Consumer; + +/** + * Uses the builder pattern to get a {@link Connection}. A {@link getConnection} + * method is provided as a convenience. + */ +public interface DataSource + extends AutoCloseable { + + /** + * Instances of this type are used to build {@link DataSource}s. This type is + * immutable once configured. No property can be set more than once. No + * property can be set after {@link build} is called. + */ + public interface Builder { + + /** + * A convenience method for setting the {@link AdbaConnectionProperty#URL}. + * + * @param url the value to be set for {@link AdbaConnectionProperty#URL} + * @return this {@link Builder} + * @see connectionProperty + */ + public default Builder url(String url) { + return connectionProperty(AdbaConnectionProperty.URL, url); + } + + /** + * A convenience method for setting the {@link AdbaConnectionProperty#USER}. + * + * @param name the value to be set for {@link AdbaConnectionProperty#USER} + * @return this {@link Builder} + * @see connectionProperty + */ + public default Builder username(String name) { + return connectionProperty(AdbaConnectionProperty.USER, name); + } + + /** + * A convenience method for setting the {@link AdbaConnectionProperty#PASSWORD}. + * + * @param password the value to be set for {@link AdbaConnectionProperty#PASSWORD} + * @return this {@link Builder} + * @see connectionProperty + */ + public default Builder password(String password) { + return connectionProperty(AdbaConnectionProperty.PASSWORD, password); + } + + /** + * Specify the value of a {@link Connection} property that will be set by default on + * all {@link Connection}s produced by this {@link DataSource}. A different value can be set + * for a particular {@link Connection} via {@link Connection.Builder#property}. + * + * @param property the {@link ConnectionProperty} to be set. May not be {@code null}. + * @param value the value to be set for {@code property} + * @return this {@link Builder} + * @throws IllegalArgumentException if {@code property.validate(value)} does not + * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if + * this property has been specified previously to this method or + * {@link connectionProperty} or {@link registerConnectionProperty}. + * @throws IllegalStateException if {@link build} has previously been called. + */ + public Builder defaultConnectionProperty(ConnectionProperty property, Object value); + + /** + * Specify the value of a {@link Connection} property that will be set on + * all {@link Connection}s produced by the built {@link DataSource}. + * Attempting to set a different value via + * {@link Connection.Builder#property} will throw + * {@link IllegalArgumentException}. + * + * @param property the {@link ConnectionProperty} to set. May not be + * {@code null}. + * @param value the value to set as the default for {@code property} + * @return this {@link Builder} + * @throws IllegalArgumentException if {@code property.validate(value)} does + * not return {@code true}. If it throws an {@link Exception} that + * {@link Exception} is the cause. Or if this property has been specified + * previously to this method or {@link defaultConnectionProperty} or + * {@link registerConnectionProperty}. + * @throws IllegalStateException if {@link build} has previously been + * called. + */ + public Builder connectionProperty(ConnectionProperty property, Object value); + + /** + * Make a user defined property known to the implementation. One reason to + * do this is so the default value of the property will be used. If the + * {@link DataSource} doesn't know about the property then it cannot know to + * set the default value. Convenience method. + * + * @param property the {@link ConnectionProperty} to make known. May not be + * {@code null}. + * @return this Builder + * @throws IllegalArgumentException if this property has been specified + * previously to this method or {@link connectionProperty} or + * {@link defaultConnectionProperty}. + * @throws IllegalStateException if {@link build} has previously been + * called. + */ + public default Builder registerConnectionProperty(ConnectionProperty property) { + return defaultConnectionProperty(property, property.defaultValue()); + } + + /** + * Return a DataSource configured as specified. + * + * @return a configured {@link DataSource}. Not {@code null}. + * @throws IllegalArgumentException if unable to return a {@link DataSource} due to + * problems with the configuration such is missing or conflicting properties. + */ + public DataSource build(); + } + + /** + * Returns a {@link Connection} builder. By default that builder will return + * {@link Connection}s with the {@code ConnectionProperty}s specified when creating this + * DataSource. Default and unspecified {@link ConnectionProperty}s can be set with + * the returned builder. + * + * @return a new {@link Connection} builder. Not {@code null}. + */ + public Connection.Builder builder(); + + /** + * Returns a {@link Connection} that has a submitted connect {@link Operation}. Convenience + * method for use with try with resources. + * + * @return a {@link Connection} + */ + public default Connection getConnection() { + return builder().build().connect(); + } + + /** + * Returns a {@link Connection} that has a submitted connect {@link Operation} with an error + * handler. Convenience method for use with try with resources. The error + * handle handles errors in the connect {@link Operation}. + * + * @param handler for errors in the connect {@link Operation} + * @return a {@link Connection} + */ + public default Connection getConnection(Consumer handler) { + return builder().build().connect(handler); + } + + /** + * Translates a SQL string from the format specified by the format argument + * to a format that can be used to create {@link Operation}s for the {@link Connection}s + * provided by this {@link DataSource}. + * + * ISSUE: Just an idea + * + * @param format not {@code null} + * @param source SQL in the format specified by {@code format}. Not {@code null}. + * @return SQL in the format supported by this {@link DataSource}. Not {@code null}. + * @throws IllegalArgumentException if the {@code format} is not supported or + * if the {@link DataSource} cannot translate the SQL + */ + public default String translateSql(String format, String source) throws SqlException { + throw new IllegalArgumentException("Unsupported format: \"" + format + "\""); + } + + /** + * Return a list of the source formats accepted by the {@link translateSql} method. + * + * ISSUE: Just an idea + * + * @return an array of Strings each of which identifies a supported format + */ + public default List supportedTranslateSqlFormats() { + return new LinkedList<>(); + } + + @Override + public void close(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.util.ServiceLoader; + +/** + * This interface supports injecting a {@link DataSourceFactory}. The SPI + * mechanism will find {@link DataSourceFactory} implementations with the + * given class name. + * + */ +public interface DataSourceFactory { + + /** + * Uses SPI to find a {@link DataSourceFactory} with the requested name or + * {@code null} if one is not found. + * + * @param name the name of the class that implements the factory + * @return a {@link DataSourceFactory} for {@code name} or {@code null} if one + * is not found + */ + public static DataSourceFactory forName(String name) { + if (name == null) throw new IllegalArgumentException("DataSourceFactory name is null"); + return ServiceLoader.load(DataSourceFactory.class).stream() + .filter(p -> p.type().getName().equals(name)).findFirst().get().get(); + } + + /** + * Returns a new {@link DataSource} builder. + * + * @return a {@link DataSource} builder. Not {@code null}. + */ + public DataSource.Builder builder(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DynamicMultiOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DynamicMultiOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * + * A multi-operation is an {@link Operation} that returns one or more results in + * addition to the result defined by the {@link Operation}. A {@link DynamicMultiOperation} is a + * multi-operation where the number and types of the results are determined at + * execution. + * + * NOTE: In general one way to do things is sufficient however the API provides + * two ways to handle multiple results. This way, the dynamic way, is required + * because the number and type of results cannot always be known in advance. The + * static way is also provided because it is much easier to use when the number + * and type of results is known. The improvement in ease of use outweighs the + * duplication IMO. If necessary one or the other can be eliminated. Eliminating + * dynamic reduces functionality. Eliminating static reduces ease of use in what + * I believe to be a common case. + * + * @param type of the result of this DynamicMultiOperation + */ +public interface DynamicMultiOperation extends OutOperation { + + /** + * Provides a handler for count results. The provided handler is called for + * each count result. When called the first argument is the number of results + * that preceeded the current result. The second argument is a CountOperation + * that will process the current result. This CountOperation has not been + * configured in any way nor has it been submitted. The handler configures the + * CountOperation and submits it. The count result is processed when the + * CountOperation is submitted. + * + * If this method is not called any count result is ignored. + * + * @param handler not null + * @return this DynamicMultiOperation + * @throws IllegalStateException if the CountOperation has not been submitted + * when the call to the handler returns + */ + public DynamicMultiOperation onCount(BiConsumer> handler); + + /** + * Provides a handler for row sequence results. The provided handler is called for + * each row sequence result. When called the first argument is the number of results + * that preceeded the current result. The second argument is a RowOperation + * that will process the current result. This RowOperation has not been + * configured in any way nor has it been submitted. The handler configures the + * RowOperation and submits it. The row sequence result is processed when the + * RowOperation is submitted. + * + * If this method is not called any row sequence result is ignored. + * + * @param handler + * @return This DynamicMultiOperation + * @throws IllegalStateException if the RowOperation has not been submitted + * when the call to the handler returns + */ + public DynamicMultiOperation onRows(BiConsumer> handler); + + /** + * Provides an error handler for this {@link Operation}. The provided handler + * is called for each error that occurs. When called the first argument is the + * number of results, including errors, that preceeded the current error. The + * second argument is a {@link Throwable} corresponding to the error. When the + * handler returns processing of the DynamicMultiOperation results continues. + * Only one onError method may be called. + * + * @param handler a BiConsumer that handles an error + * @return this DynamicMultiOperation + * @throws IllegalStateException if any onError method was called previously + */ + public DynamicMultiOperation onError(BiConsumer handler); + + // Covariant overrides + + /** + * Provides an error handler for this {@link Operation}. If execution of this + * {@link Operation} results in an error, before the Operation is completed, + * the handler is called with the {@link Throwable} as the argument. When the + * handler returns the {@link Operation} is completed exceptionally with the + * {@link Throwable}. + * + * @param handler + * @return this DynamicMultiOperation + * @throws IllegalStateException if any onError method was called previously + */ + @Override + public DynamicMultiOperation onError(Consumer handler); + + @Override + public DynamicMultiOperation outParameter(String id, SqlType type); + + @Override + public DynamicMultiOperation apply(Function processor); + + @Override + public DynamicMultiOperation set(String id, Object value); + + @Override + public DynamicMultiOperation set(String id, Object value, SqlType type); + + @Override + public DynamicMultiOperation set(String id, CompletionStage source); + + @Override + public DynamicMultiOperation set(String id, CompletionStage source, SqlType type); + + @Override + public DynamicMultiOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.Callable; +import java.util.function.Consumer; + +/** + * An {@link Operation} that calls a user defined function when executed. Does + * not perform any database action. The result of a {@link LocalOperation} is + * the result of calling the {@link Callable}. This type allows user code to + * execute arbitrary code at particular points in the sequence of + * {@link Operation}s executed by a {@link Connection} without having to execute + * a specific database action at the same time. + * + * @param the type of the result of this {@link Operation} + */ +public interface LocalOperation extends Operation { + + /** + * Provides a result processor for this {@link Operation}. The result + * processor is called when this {@link LocalOperation} is executed. The + * result of this {@link LocalOperation} is the result of calling + * {@code callable}. + * + * @param callable the result processor called when this {@link Operation} is + * executed + * @return this {@link LocalOperation} + * @throws IllegalStateException if this method has already been called or + * this {@link Operation} has been submitted. + */ + public LocalOperation onExecution(Callable callable); + + @Override + public LocalOperation onError(Consumer handler); + + @Override + public LocalOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.function.Consumer; + +/** + * A description of some work to be done by the database and how to process the + * database output. An {@link Operation} is created by an + * {@link OperationGroup}, configured and submitted. If not submitted it is not + * executed. If submitted it is possibly executed according to the attributes of + * the {@link OperationGroup} that created it. + * + * Note: A {@link Connection} is an {@link OperationGroup} and so can create + * {@link Operation}s. + * + * @param the type of the result of the {@link Operation} + */ +public interface Operation { + + /** + * Provides an error handler for this {@link Operation}. If execution of this + * {@link Operation} results in an error, before the Operation is completed, + * the handler is called with the {@link Throwable} as the argument. + * + * @param handler + * @return this {@link Operation} + */ + public Operation onError(Consumer handler); + + /** + * The minimum time before this {@link Operation} might be canceled + * automatically. The default value is forever. The time is + * counted from the beginning of Operation execution. The Operation will not + * be canceled before {@code minTime} after the beginning of execution. + * Some time at least {@code minTime} after the beginning of execution, + * an attempt will be made to cancel the {@link Operation} if it has not yet + * completed. Implementations are encouraged to attempt to cancel within a + * reasonable time, though what is reasonable is implementation dependent. + * + * @param minTime minimum time to wait before attempting to cancel + * @return this Operation + * @throws IllegalArgumentException if minTime <= 0 seconds + * @throws IllegalStateException if this method is called more than once on + * this operation + */ + public Operation timeout(Duration minTime); + + /** + * Add this {@link Operation} to the tail of the {@link Operation} collection + * of the {@link Connection} that created this {@link Operation}. An + * {@link Operation} can be submitted only once. Once an {@link Operation} is + * submitted it is immutable. Any attempt to modify a submitted + * {@link Operation} will throw {@link IllegalStateException}. + * + * @return a {@link Submission} for this {@link Operation} + * @throws IllegalStateException if this method is called more than once on + * this operation + */ + public Submission submit(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; +import java.util.function.Consumer; +import java.util.logging.Logger; +import java.util.stream.Collector; + +/** + * A set of {@link Operation}s that share certain properties, are managed as a + * unit, and are executed as a unit. The {@link Operation}s created by an + * {@link OperationGroup} and submitted are the member {@link Operation}s of + * that {@link OperationGroup}. An {@link OperationGroup} is not a transaction + * and is not related to a transaction in any way. + * + * An {@link OperationGroup} conceptually has a collection of member + * {@link Operation}s. When an {@link OperationGroup} is submitted it is placed + * in the collection of the {@link OperationGroup} of which it is a member. The + * member {@link OperationGroup} is executed according to the attributes of the + * {@link OperationGroup} of which it is a member. The member {@link Operation}s + * of an {@link OperationGroup} are executed according to the attributes of that + * {@link OperationGroup}. + * + * How an {@link OperationGroup} is executed depends on its attributes. + * + * If an {@link OperationGroup} has a condition and the value of that condition + * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below. + * If it is {@link Boolean#FALSE} then the {@link OperationGroup} is completed + * with the value null. If the condition completed exceptionally then the + * {@link OperationGroup} is completed exceptionally with a + * {@link SqlSkippedException} that has that exception as its cause. + * + * If the {@link OperationGroup} is sequential the member {@link Operation}s are + * executed in the order they were submitted. If it is parallel, they may be + * executed in any order including simultaneously. + * + * If an {@link OperationGroup} is dependent and a member {@link Operation} + * completes exceptionally the remaining member {@link Operation}s in the + * collection are completed exceptionally with a {@link SqlSkippedException} + * that has the initial {@link Exception} as its cause and the {@link OperationGroup} + * is completed exceptionally with the initial {@link Exception}. A member + * {@link Operation} in-flight may either complete normally or be completed + * exceptionally but must complete one way or the other. [NOTE: Too strong?] + * + * If an {@link OperationGroup} is held additional member {@link Operation}s may + * be submitted after the {@link OperationGroup} is submitted. If an + * {@link OperationGroup} is not held, no additional member {@link Operation}s + * may be submitted after the {@link OperationGroup} is submitted. If an + * {@link OperationGroup} is held it will be completed only after it is released + * or if conditional and the condition is not {@link Boolean#TRUE}. If a + * {@link OperationGroup} is dependent, held, one of its member + * {@link Operation}s completed exceptionally, and its queue is empty then the + * {@link OperationGroup} is released. + * + * The result of this {@link OperationGroup} is the result of collecting the + * results of its member {@link Operation}s. If the {@link OperationGroup} is + * dependent and one of its member {@link Operation}s completes exceptionally, + * the {@link OperationGroup} is completed exceptionally. + * + * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is a + * intentional limitation but may be a simplification we can live with. Or not. + * + * @param The type of the result of the member {@link Operation}s + * @param The type of the collected results the member {@link Operation}s + */ +public interface OperationGroup extends Operation { + + /** + * Mark this {@link OperationGroup} as parallel. If this method is not called + * the {@link OperationGroup} is sequential. If an {@link OperationGroup} is + * parallel, member {@link Operation}s may be executed in any order including + * in parallel. If an {@link OperationGroup} is sequential, the default, + * member {@link Operation}s are executed strictly in the order they are + * submitted. + * + * Note: There is no covariant override of this method in {@link Connection} + * as there is only a small likelihood of needing it. + * + * @return this {@link OperationGroup} + * @throws IllegalStateException if this {@link OperationGroup} has been + * submitted or any member {@link Operation}s have been created. + */ + public OperationGroup parallel(); + + /** + * Mark this {@link OperationGroup} as independent. If this method is not + * called the {@link OperationGroup} is dependent, the default. If an + * {@link OperationGroup} is independent then failure of one member + * {@link Operation} does not affect the execution of other member + * {@link Operation}s. If an {@link OperationGroup} is dependent then failure + * of one member {@link Operation} will cause all member {@link Operation}s + * remaining in the queue to be completed exceptionally with a + * {@link SqlSkippedException} with the cause set to the original exception. + * + * The result of this {@link OperationGroup}'s execution is the result of collecting the + * results of the member {@link Operation}s that complete normally. + * + * Note: There is no covariant override of this method in {@link Connection} + * as there is only a small likelihood of needing it. + * + * @return this {@link OperationGroup} + * @throws IllegalStateException f this {@link OperationGroup} blocks errors + * or if this {@link OperationGroup} has been submitted or any member + * {@link Operation}s have been created + */ + public OperationGroup independent(); + + /** + * Define a condition that determines whether the member {@link Operation}s of + * this {@link OperationGroup} are executed or not. If and when this + * {@link OperationGroup} is executed then if the condition argument is + * completed with {@link Boolean#TRUE} the member {@link Operation}s are + * executed. If {@link Boolean#FALSE} or if it is completed exceptionally the + * member {@link Operation}s are not executed but are removed from the queue. + * After all member {@link Operation}s have been removed from the queue this + * {@link OperationGroup} is completed with {@code null}. + * + * Note: There is no covariant override of this method in Connection as there + * is only a small likelihood of needing it. + * + * ISSUE: Should the member Operations be skipped or otherwise completed + * exceptionally? + * + * @param condition a {@link CompletionStage} the value of which determines + * whether this {@link OperationGroup} is executed or not + * @return this OperationGroup + * @throws IllegalStateException iif this {@link OperationGroup} has been + * submitted or any member {@link Operation}s have been created + */ + public OperationGroup conditional(CompletionStage condition); + + /** + * Mark this {@link OperationGroup} as held. It can be executed but cannot be + * completed. A {@link OperationGroup} that is held remains in the queue even + * if all of its current member {@link Operation}s have completed. So long as + * the {@link OperationGroup} is held new member {@link Operation}s can be + * submitted. A {@link OperationGroup} that is held must be released before it + * can be completed and removed from the queue. + * + * Note: There is no covariant override of this method in Connection as there + * is only a small likelihood of needing it. + * + * ISSUE: Need a better name. + * + * @return a Submission + * @throws IllegalStateException if this {@link OperationGroup} has been + * submitted + */ + public Submission submitHoldingForMoreMembers(); + + /** + * Allow this {@link OperationGroup} to be completed and removed from the + * queue once all of its member {@link Operation}s have been completed. After + * this method is called no additional member {@link Operation}s can be + * submitted. Once all member {@link Operation}s have been removed from the + * queue this {@link OperationGroup} will be completed and removed from the + * queue. + * + * Calling this method when this {@link OperationGroup} is not held is a + * no-op. + * + * Note: There is no covariant override of this method in Connection as there + * is only a small likelihood of needing it. + * + * ISSUE: Need a better name. + * + * @return this OperationGroup + * @throws IllegalStateException if this {@link OperationGroup} has been + * completed + */ + public OperationGroup releaseProhibitingMoreMembers(); + + /** + * Provides a {@link Collector} to reduce the results of the member + * {@link Operation}s. The result of this {@link OperationGroup} is the result + * of calling finisher on the final accumulated result.If the + * {@link Collector} is {@link Collector.Characteristics#UNORDERED} the member + * {@link Operation} results may be accumulated out of order.If the + * {@link Collector} is {@link Collector.Characteristics#CONCURRENT} then the + * member {@link Operation} results may be split into subsets that are reduced + * separately and then combined. If this {@link OperationGroup} is sequential, + * the characteristics of the {@link Collector} only affect how the results of + * the member {@link Operation}s are collected; the member {@link Operation}s + * are executed sequentially regardless. If this {@link OperationGroup} is + * parallel the characteristics of the {@link Collector} may influence the + * execution order of the member {@link Operation}s. + * + * The default value is + * {@code Collector.of(()->null, (a,t)->{}, (l,r)->null, a->null)}. + * + * @param c the Collector. Not null. + * @return This OperationGroup + * @throws IllegalStateException if called more than once or if this + * {@link OperationGroup} has been submitted + */ + public OperationGroup collect(Collector c); + + /** + * Returns an Operation that is never skipped. Skipping stops with a catchOperation + * and the subsequent Operation is executed normally. The value of a + * catchOperation is always null. + * + * @return an unskippable Operation; + */ + public Operation catchOperation(); + + /** + * Creates and submits a catch Operation. Convenience method. + * + * @return this OperationGroup + */ + public default OperationGroup catchErrors() { + catchOperation().submit(); + return this; + } + + /** + * Return a new {@link ArrayCountOperation}. + *

+ * Usage Note: Frequently use of this method will require a type witness to + * enable correct type inferencing. + *


+   *   conn.<List<Integer>>arrayCountOperation(sql)
+   *     .set ...
+   *     .collect ...
+   *     .submit ...
+   * 
+ * + * @param the result type of the returned {@link ArrayCountOperation} + * @param sql SQL to be executed. Must return an update count. + * @return a new {@link ArrayCountOperation} that is a member of this + * {@link OperationGroup} + */ + public ArrayCountOperation arrayCountOperation(String sql); + + /** + * Return a new {@link CountOperation}. + * + * @param the result type of the returned {@link CountOperation} + * @param sql SQL to be executed. Must return an update count. + * @return an new {@link CountOperation} that is a member of this + * {@link OperationGroup} + * + */ + public ParameterizedCountOperation countOperation(String sql); + + /** + * Return a new {@link Operation} for a SQL that doesn't return any result, + * for example DDL. The result of this Operation is always null. + * + * @param sql SQL for the {@link Operation}. + * @return a new {@link Operation} that is a member of this + * {@link OperationGroup} + */ + public Operation operation(String sql); + + /** + * Return a new {@link OutOperation}. The SQL must return a set of zero or + * more out parameters or function results. + * + * @param the result type of the returned {@link OutOperation} + * @param sql SQL for the {@link Operation}. Must return zero or more out + * parameters or function results. + * @return a new {@link OutOperation} that is a member of this + * {@link OperationGroup} + */ + public OutOperation outOperation(String sql); + + /** + * Return a {@link ParameterizedRowOperation}. + * + * @param the type of the result of the returned + * {@link ParameterizedRowOperation} + * @param sql SQL for the {@link Operation}. Must return a row sequence. + * @return a new {@link ParameterizedRowOperation} that is a member of this + * {@link OperationGroup} + */ + public ParameterizedRowOperation rowOperation(String sql); + + public RowProcessorOperation rowProcessorOperation(String sql); + + /** + * Return a {@link StaticMultiOperation}. + * + * @param the type of the result of the returned + * {@link StaticMultiOperation} + * @param sql SQL for the {@link Operation} + * @return a new {@link StaticMultiOperation} that is a member of this + * {@link OperationGroup} + */ + public StaticMultiOperation staticMultiOperation(String sql); + + /** + * Return a {@link DynamicMultiOperation}. Use this when the number and type + * of the results is not knowable. + * + * @param the type of the result of the returned + * {@link DynamicMultiOperation} + * @param sql SQL for the {@link Operation} + * @return a new {@link DynamicMultiOperation} that is a member of this + * {@link OperationGroup} + */ + public DynamicMultiOperation dynamicMultiOperation(String sql); + + /** + * Return an {@link Operation} that ends the database transaction. The + * transaction is ended with a commit unless the {@link Transaction} has been + * {@link Transaction#setRollbackOnly} in which case the transaction is ended + * with a rollback. + * + * The type argument {@link S} of the containing {@link OperationGroup} must + * be a supertype of {@link TransactionOutcome}. + * + * @param trans the Transaction that determines whether the Operation does a + * database commit or a database rollback. + * @return an {@link Operation} that will end the database transaction. + * @throws IllegalStateException if this {@link OperationGroup} has been + * submitted and is not held or is parallel. + */ + public Operation endTransactionOperation(Transaction trans); + + /** + * Convenience method that creates and submits a endTransaction + * {@link Operation} that commits by default but can be set to rollback by + * calling {@link Transaction#setRollbackOnly}. + * + * @param trans the Transaction that determines whether the Operation is a + * database commit or a database rollback. + * @return this {@link OperationGroup} + * @throws IllegalStateException if this {@link OperationGroup} has been + * submitted and is not held or is parallel. + */ + public default CompletionStage commitMaybeRollback(Transaction trans) { + return this.endTransactionOperation(trans).submit().getCompletionStage(); + } + + /** + * Return a {@link LocalOperation}. + * + * @param value type of the returned local Operation + * @return a LocalOperation + * @throws IllegalStateException if this OperationGroup has been submitted and + * is not held + */ + public LocalOperation localOperation(); + + /** + * Returns a Flow.Processor that subscribes to a sequence of Operations and + * produces a sequence of corresponding Submissions.The Operations must be + * members of this OperationGroup. Calling Subscription.onNext with any + * Operation that is not a member of this OperationGroup, that is was not + * created by calling one of the Operation factory methods on this + * OperationGroup, will cause the Subscription to be canceled and call + * Subscriber.onError with IllegalArgumentException. The method + * Subscription.onNext will call submit on each Operation it is passed and + * publish the resulting Submission. Since an Operation can only be submitted + * once, submitting an Operation and calling onNext with that submitted + * Operation will cause the Subscription to be canceled and Subscriber.onError + * to be called with IllegalStateException. The Processor does not retain + * Submissions to produce to a subsequently attached Subscriber. + * + * If there is no Subscriber to the Processor, the Processor will request + * Operations as appropriate. If there is a Subscriber to the Processor, the + * Processor will request Operations no faster than the Subscriber requests + * Submissions. + * + * Each call to this method returns a new Flow.processor. The Submissions + * published to each Processor are exactly those generated by calling submit + * on the Operations passed as arguments to onNext on the same Processor. + * Calling this method while there is an active Processor will throw + * IllegalStateException. + * + * Note: If any Operation is submitted directly, that is by calling submit + * rather than passing it to onNext, the Submission returned by the submit + * call will not be published. + * + * @param + * @return a Flow.Processor that accepts Operations and generates Submissions + * @throws IllegalStateException if there is an active Processor + */ + public Flow.Processor, Submission> operationProcessor(); + + /** + * Supply a {@link Logger} for the implementation of this + * {@link OperationGroup} to use to log significant events. Exactly what + * events are logged, at what Level the events are logged and with what + * parameters is implementation dependent. All member {@link Operation}s of + * this {@link OperationGroup} will use the same {@link Logger} except a + * member {@link OperationGroup} that is supplied with a different + * {@link Logger} uses that {@link Logger}. + * + * Supplying a {@link Logger} configured with a + * {@link java.util.logging.MemoryHandler} with the + * {@link java.util.logging.MemoryHandler#pushLevel} set to + * {@link java.util.logging.Level#WARNING} will result in no log output in + * normal operation. In the event of an error the actions leading up to the + * error will be logged. + * + * Implementation Note: Implementations are encouraged to log the creation of + * this {@link OperationGroup} set to {@link java.util.logging.Level#INFO}, + * the creation of member {@link Operation}s at the + * {@link java.util.logging.Level#CONFIG} level, and execution of member + * {@link Operation}s at the {@link java.util.logging.Level#FINE} level. + * Detailed information about the execution of member {@link Operation}s may + * be logged at the {@link java.util.logging.Level#FINER} and + * {@link java.util.logging.Level#FINEST} levels. Errors in the execution of + * user code should be logged at the {@link java.util.logging.Level#WARNING} + * Level. Errors in the implementation code should be logged at the + * {@link java.util.logging.Level#SEVERE} Level. + * + * @param logger used by the implementation to log significant events + * @return this {@link OperationGroup} + */ + public OperationGroup logger(Logger logger); + + // Covariant overrides + @Override + public OperationGroup timeout(Duration minTime); + + @Override + public OperationGroup onError(Consumer handler); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OutOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OutOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * An {@link ParameterizedOperation} for which the result is a set of out parameter + * values and/or function results. As the SQL is vendor specific, how parameters + * are represented in the SQL is itself vendor specific. + * + * @param the type of the result of this {@link Operation} + */ +public interface OutOperation extends ParameterizedOperation { + + /** + * Register an out parameter identified by the given id. + * + * @param id the parameter identifier + * @param type the SQL type of the value of the parameter + * @return this {@link OutOperation} + * @throws IllegalArgumentException if id is not a parameter marker in the SQL + * @throws IllegalStateException if this method has been called previously on + * this {@link Operation} with the same id or this {@link OutOperation} has been submitted + */ + public OutOperation outParameter(String id, SqlType type); + + /** + * Provide a processor that will handle the result of executing the SQL. + * + * @param processor the {@link Function} that will be called to process the result of + * this {@link OutOperation} + * @return this {@link OutOperation} + * @throws IllegalStateException if this method has been called previously on + * this {@link Operation} or this {@link Operation} has been submitted. + */ + public OutOperation apply(Function processor); + + // Covariant overrides + + @Override + public OutOperation onError(Consumer handler); + + @Override + public OutOperation set(String id, Object value); + + @Override + public OutOperation set(String id, Object value, SqlType type); + + @Override + public OutOperation set(String id, CompletionStage source); + + @Override + public OutOperation set(String id, CompletionStage source, SqlType type); + + @Override + public OutOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedCountOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedCountOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * A {@link ParameterizedCountOperation} is a {@link ParameterizedOperation} that returns a count. + * + * @param the type of the result of this {@link Operation} + */ +public interface ParameterizedCountOperation extends ParameterizedOperation, CountOperation { + + /** + * Returns a {@link RowOperation} to process the auto-generated keys, if any, returned + * by this {@link Operation}. If no keys are named the columns of the returned + * rows are implementation dependent. If keys are specified the columns of the + * returned rows are the keys. The {@link RowOperation} must be submitted before this + * {@link Operation} is submitted. If it has not submitting this {@link Operation} will + * result throw {@link IllegalStateException}. + * + * ISSUE: Should this be in {@link CountOperation}? + * + * @param keys the names of the returned columns or null. + * @return A RowOperation that will process the auto-generated keys + * @throws IllegalStateException if this method has already been called on this + * {@link Operation} or if this {@link Operation} has already been submitted. + */ + public RowOperation returning(String ... keys); + + // Covariant overrides + + @Override + public ParameterizedCountOperation onError(Consumer handler); + + @Override + ParameterizedCountOperation apply(Function processor); + + @Override + public ParameterizedCountOperation set(String id, Object value); + + @Override + public ParameterizedCountOperation set(String id, Object value, SqlType type); + + @Override + public ParameterizedCountOperation set(String id, CompletionStage source); + + @Override + public ParameterizedCountOperation set(String id, CompletionStage source, SqlType type); + + @Override + public ParameterizedCountOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.util.concurrent.CompletionStage; + +/** + * An Operation that has in parameters. + * + * As the SQL is vendor specific, how parameters are represented in the SQL is + * itself vendor specific. + * + * For positional parameters, those where all parameters are indicated by the + * same character sequence, for example '?', it is recommended that the + * parameter id be the decimal integer representation of the parameter number. + * + * A SQL structured type passed as an argument to a set method must be created + * by the same {@link Connection} that the created the + * {@link ParameterizedOperation}. If not {@link IllegalArgumentException} is + * thrown. A SQL structured type is one of + * {@link SqlArray}, {@link SqlBlob}, {@link SqlClob}, {@link SqlRef} or + * {@link SqlStruct}. This limitation holds recursively for all components of + * a SQL structured type. An implementation may relax this constraint. + * + * @param the type of the result of this {@link Operation} + */ +public interface ParameterizedOperation extends Operation { + + /** + * Set a parameter value. The value is captured and should not be modified + * before the {@link Operation} is completed. + * + * @param id the identifier of the parameter marker to be set + * @param value the value the parameter is to be set to + * @param type the SQL type of the value to send to the database + * @return this Operation + */ + public ParameterizedOperation set(String id, Object value, SqlType type); + + /** + * Set a parameter value. Use a default SQL type determined by the type of the + * value argument. The value is captured and should not be modified before the + * {@link Operation} is completed. + * + * @param id the identifier of the parameter marker to be set + * @param value the value the parameter is to be set to + * @return this {@link Operation} + */ + public ParameterizedOperation set(String id, Object value); + + /** + * Set a parameter value to be the value of a + * {@link java.util.concurrent.CompletionStage}. The {@link Operation} will + * not be executed until the {@link java.util.concurrent.CompletionStage} is + * completed. This method allows submitting {@link Operation}s that depend on + * the result of previous {@link Operation}s rather than requiring that the + * dependent {@link Operation} be submitted only when the previous + * {@link Operation} completes. + * + * @param id the identifier of the parameter marker to be set + * @param source the {@link java.util.concurrent.CompletionStage} that provides + * the value the parameter is to be set to + * @param type the SQL type of the value to send to the database + * @return this {@link Operation} + */ + public ParameterizedOperation set(String id, CompletionStage source, SqlType type); + + /** + * Set a parameter value to be the future value of a + * {@link java.util.concurrent.CompletionStage}. The {@link Operation} will + * not be executed until the {@link java.util.concurrent.CompletionStage} is + * completed. This method allows submitting {@link Operation}s that depend on + * the result of previous {@link Operation}s rather than requiring that the + * dependent {@link Operation} be submitted only when the previous + * {@link Operation} completes. Use a default SQL type determined by the type + * of the value of the {@link java.util.concurrent.CompletionStage} + * argument. + * + * @param id the identifier of the parameter marker to be set + * @param source the {@link java.util.concurrent.CompletionStage} that + * provides the value the parameter is to be set to + * @return this {@link Operation} + */ + public ParameterizedOperation set(String id, CompletionStage source); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.stream.Collector; + +/** + * An Operation that accepts parameters and processes a sequence of rows. + * + * @param the type of the result of this {@link Operation} + */ +public interface ParameterizedRowOperation extends ParameterizedOperation, RowOperation { + + // Covariant overrides + + @Override + public ParameterizedRowOperation onError(Consumer handler); + + @Override + public ParameterizedRowOperation fetchSize(long rows) throws IllegalArgumentException; + + @Override + public ParameterizedRowOperation collect(Collector c); + + @Override + public ParameterizedRowOperation set(String id, Object value, SqlType type); + + @Override + public ParameterizedRowOperation set(String id, CompletionStage source, SqlType type); + + @Override + public ParameterizedRowOperation set(String id, CompletionStage source); + + @Override + public ParameterizedRowOperation set(String id, Object value); + + @Override + public ParameterizedRowOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Result.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Result.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.util.concurrent.CompletionStage; + +/** + * All or part of the result of a database operation (lower case). + * + * A {@link Result} is valid only for the duration of the call it is passed to. Once + * that call has returned, the {@link Result} passed to that call is invalid and any + * calls to it throw {@link IllegalStateException}. {@link Result}s are not required to be + * thread-safe. + * + */ +public interface Result { + + /** + * A {@link Result} that is just a number of rows modified, a {@link Long}. + * + * Note: It is certainly true that this is not needed; {@link Long} could be used + * instead. Seems like there might be a documentational advantage to having + * this type. If you don't like it, just mentally replace it with {@link Long} + * everywhere it appears. + */ + public static interface Count extends Result { + + /** + * + * @return + */ + public long getCount(); + } + + /** + * A {@link Result} where the components can be retrieved by name. What + * constitutes a name is implementation dependent. + * + */ + public static interface ResultMap extends Result { + + /** + * Return the value indicated by the {@code id}. The {@code id} may be either the id for an + * OUT parameter marker or for a column. See {@link OutOperation} and + * {@link RowOperation}. + * + * @param the type of the returned value + * @param id the name of the column or OUT parameter marker + * @param type the value indicated by {@code id} is converted to this type + * @return a value of type {@code T} + * @throws IllegalArgumentException if id is not the identifier of a value + * in this {@link ResultMap} + * @throws IllegalStateException if the call that was passed this {@link ResultMap} has + * ended + * @throws ClassCastException if the returned value cannot be converted to the + * specified type -- ISSUE: Not really a class cast. Maybe a new unchecked exception. + */ + public T get(String id, Class type); + + /** + * Returns a {@code {@link String}[]} that contains the identifiers that reference the + * values of this {@link ResultMap} in the same order these values are returned by the + * database. A {@code null} value in the array means there is a returned value for + * which no identifier was defined. There is no way to retrieve such a + * value. + * + * By default the values in the array are the identifier portion of the out + * parameter markers in the SQL. Alternatively the implementation may assign + * other identifiers, typically column names or aliases. If there + * are values that have no associated identifier the corresponding value in + * the array will be null. + * + * @return an array containing the value identifiers. Not {@code null}. + * @throws IllegalStateException if the call that was passed this {@link ResultMap} has + * ended + */ + public String[] getIdentifiers(); + } + + /** + * Used by {@link OutOperation} to expose the out parameters of a call. + */ + public static interface OutParameterMap extends ResultMap { + } + + /** + * Used by {@link RowOperation} to expose each row of a row sequence. + */ + public static interface Row extends ResultMap { + + /** + * The count of {@link Row}s in the {@link Row} sequence preceeding this {@link Row}. For the first + * row in the Row sequence the {@link rowNumber} is 0. + * + * @return the count of {@link Row}s in the {@link Row} sequence preceeding this {@link Row} + * @throws IllegalStateException if the call that was passed this {@link Result} has + * ended + */ + public long rowNumber(); + + /** + * Is this the last {@link Row} of the row sequence. If true then the result of the + * call that was passed this {@link Row} is the result of the {@link Operation}. + * + * @return a {@link java.util.concurrent.CompletionStage} the value of which + * will be true iff this the last {@link Row} of a row sequence and false otherwise + * @throws IllegalStateException if the call that was passed this {@link Result} has + * ended + */ + public CompletionStage isLast(); + + /** + * Terminate processing of the rows in this {@link RowOperation}. The result of the + * call that was passed this {@link Row} will be the result of the {@link Operation}. No + * further rows in the row sequence will be processed. All subsequent rows, + * if any, will be ignored. Any rows already fetched will not be processed. + * Any rows not yet fetched may or may not be fetched. If fetched they will + * not be processed. + * + * @throws IllegalStateException if the call that was passed this {@link Result} has + * ended + */ + public void cancel(); + + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.util.function.Consumer; +import java.util.stream.Collector; + +/** + * A {@link RowOperation} is a database operation that returns a row sequence. + * + * @param the type of the result of this {@link Operation} + */ +public interface RowOperation extends Operation { + + /** + * A hint to the implementation of how many rows to fetch in each database + * access. Implementations are free to ignore it. + * + * @param rows suggested number of rows to fetch per access + * @return this {@link RowOperation} + * @throws IllegalArgumentException if row < 1 + * @throws IllegalStateException if this method had been called previously or + * this Operation has been submitted. + */ + public RowOperation fetchSize(long rows) throws IllegalArgumentException; + + /** + * Provides a {@link Collector} to reduce the sequence of rows.The result of + * the {@link Operation} is the result of calling finisher on the final + * accumulated result. If the {@link Collector} is + * {@link Collector.Characteristics#UNORDERED} rows may be accumulated out of + * order. If the {@link Collector} is + * {@link Collector.Characteristics#CONCURRENT} then the sequence of rows may be + * split into subsequences that are reduced separately and then combined. + * + * @param
the type of the accumulator + * @param the type of the final result + * @param c the Collector. Not null. + * @return This RowOperation + * @throws IllegalStateException if this method had been called previously or + * this Operation has been submitted. + */ + public RowOperation collect(Collector c); + + @Override + public RowOperation onError(Consumer handler); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowProcessorOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowProcessorOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; +import java.util.function.Consumer; + +/** + * A RowProcessorOperation handles a database action that returns a sequence of + * rows. The rows are handled by a java.util.concurrent.Flow.Processor. A + * RowProcessorOperation is conceptually a Row Publisher and a result Subscriber. + * The configured Processor transforms the Row stream into a result stream. + * Configuring a Processor causes the RowProcessorOperation to subscribe the + * Processor to the stream of rows and for the RowProcessorOperation itself to + * subscribe to the stream of results published by the Processor. The last + * result produced is the result of the RowProcessorOperation. + * + * The RowProcessorOperation will insure that the demand for results is positive. + * + * Calling Submission.cancel will call cancel on the result Subscription. The + * Processor should call cancel on the row Subscription when cancel is called on + * the result Subscription. + * + * @param the type of the result of the {@link Operation} + */ +public interface RowProcessorOperation extends ParameterizedOperation { + + /** DRAFT + * Accepts a Processor that subscribes to a stream of Rows and publishes + * a stream of result values. This Operation will subscribe to the stream of + * results. The last published result value is the result of the + * Operation. + * + * This Operation will insure result demand is eventually positive until + * resultSubscriber.onComplete or resultSubscriber.onError is called. This + * Operation will call resultSubscription.cancel if this Operation is canceled. + * + * While there are more rows and row demand is positive and rowSubscription.cancel + * has not been called, this Operation will eventually call rowToResult.onNext + * with the next row in the row sequence. The Result.Row argument to onNext is + * only valid for the duration of that call. When there are no more Rows this + * Operation will call rowToResult.onComplete. If there is an error this + * Operation will call rowToResult.onError with the appropriate Exception whether + * or not any rows were published. + * + * If resultSubscriber.onError is called this Operation completes + * exceptionally with the passed exception. After all rows are published if + * neither resultSubscriber.onComplete or resultSubscriber.onError is + * called this Operation will complete exceptionally after the inactivity + * timeout expires. + * + * If this Operation is skipped it will be completed exceptionally with + * SqlSkippedException but no calls will be made to rowToResult. + * + * Calling Row.cancel is the same as calling Subscription.cancel on the Row + * Subscription. + * + * @param rowToResult subscribes to a stream of Result.Rows and publishes a + * stream of results of type T + * @return this RowProcessorOperation + */ + public RowProcessorOperation rowProcessor(Flow.Processor rowToResult); + + /** DRAFT + * Subscribe to the stream of Rows returned by this Operation. The result of + * this Operation is null. This is a convenience method. + * + * @param rowSubscriber + * @return this RowProcessorOperation + */ + public default RowProcessorOperation subscribe(Flow.Subscriber rowSubscriber) { + + // create a Row to result Processor that passes the Rows to rowSubscriber + // and publishes a single null as its only result. + Flow.Processor rowToResult + = new Flow.Processor() { + + protected boolean isResultPending = false; + protected long resultDemand = 0; + + protected Flow.Subscription rowSubscription; + + protected Flow.Subscriber resultSubscriber; + + protected Flow.Subscription resultSubscription = new Flow.Subscription() { + @Override + public void request(long n) { + resultDemand += n; + if (isResultPending && resultDemand > 0) { + resultSubscriber.onNext(null); + resultDemand--; + resultSubscriber.onComplete(); + isResultPending = false; + } + } + + @Override + public void cancel() { + rowSubscription.cancel(); + } + }; + + @Override + public void onSubscribe(Flow.Subscription subscription) { + rowSubscription = subscription; + rowSubscriber.onSubscribe(rowSubscription); + + } + + @Override + public void onNext(Result.Row item) { + rowSubscriber.onNext(item); + } + + @Override + public void onError(Throwable throwable) { + rowSubscriber.onError(throwable); + resultSubscriber.onError(throwable); + } + + @Override + public void onComplete() { + rowSubscriber.onComplete(); + if (resultDemand > 0) { + resultSubscriber.onNext(null); + resultSubscriber.onComplete(); + } else { + isResultPending = true; + } + } + + @Override + public void subscribe(Flow.Subscriber subscriber) { + resultSubscriber = subscriber; + resultSubscriber.onSubscribe(resultSubscription); + } + }; + + return rowProcessor(rowToResult); + } + + /** DRAFT + * Sets the minimum time the Operation will wait for Processor activity before + * terminating. If all of the following hold for some time exceeding minTime, + * this Operation will be completed exceptionally with + * {@link java.util.concurrent.TimeoutException}. + *
    + *
  • no calls to the onNext, onComplete, or onError methods of the result + * Subscriber, ie the Subscriber passed to rowToResult.subscribe
  • + *
  • the demand for Rows is zero or all rows have been published
  • + *
+ * If the Operation can publish no more rows either because all rows have + * been published or because the demand for rows is 0 and rowToResult + * has neither published a result nor terminated the stream and this state has + * continued for at least minTime, the Operation is completed exceptionally. + * + * The default value is one minute. + * + * Note: The minTime parameter value must be small to guarantee that the + * Connection does not hang for long periods. The default is large enough + * that it most likely is insignificant for most apps, but small enough to + * kick loose a hung Connection in semi-reasonable time. + * + * @param minTime minimum time with the Processor making no progress before the + * Operation is terminated. + * @return this RowProcessorOperation + */ + public RowProcessorOperation inactivityTimeout(Duration minTime); + + + // Covariant overrides + + @Override + public RowProcessorOperation onError(Consumer handler); + + @Override + public RowProcessorOperation set(String id, Object value, SqlType type); + + @Override + public RowProcessorOperation set(String id, CompletionStage source, SqlType type); + + @Override + public RowProcessorOperation set(String id, CompletionStage source); + + @Override + public RowProcessorOperation set(String id, Object value); + + @Override + public RowProcessorOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ShardingKey.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ShardingKey.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +/** + * Interface used to indicate that this object represents a Sharding Key. A + * {@link ShardingKey} instance is only guaranteed to be compatible with the + * data source instance that it was derived from. A {@link ShardingKey} is + * created using {@link Builder}. + *

+ * The following example illustrates the use of {@link Builder} to create a + * {@link ShardingKey}: + *

+ * {@code
+ *
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ *                           .subkey("abc", JDBCType.VARCHAR)
+ *                           .subkey(94002, JDBCType.INTEGER)
+ *                           .build();
+ * }
+ * 
+ *

+ * + * A {@link ShardingKey} is used for specifying a + * {@link AdbaConnectionProperty#SHARDING_KEY} or a + * {@link AdbaConnectionProperty#SHARDING_GROUP_KEY}. Databases that support + * composite Sharding may use a * to specify a additional level of partitioning + * within to specify a additional level of partitioning within the Shard. + *

+ * The following example illustrates the use of {@link Builder} to create a + * {@link AdbaConnectionProperty#SHARDING_GROUP_KEY} for an eastern region with + * a {@link AdbaConnectionProperty#SHARDING_KEY} specified for the Pittsburgh + * branch office: + *

+ * {@code
+ *
+ *     DataSource ds = new MyDataSource();
+ *     ShardingKey superShardingKey = ds.shardingKeyBuilder()
+ *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ *                           .build();
+ *     ShardingKey shardingKey = ds.shardingKeyBuilder()
+ *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ *                           .build();
+ *     Connection con = ds.builder()
+ *                           .property(SHARDING_GROUP_KEY, superShardingKey)
+ *                           .property(SHARDING_KEY, shardingKey)
+ *                           .build();
+ * }
+ * 
+ */ +public interface ShardingKey { + + /** + * A builder created from a {@link DataSource} or object, used to create a + * {@link ShardingKey} with sub-keys of supported data types. Implementations + * must support JDBCType.VARCHAR and may also support additional data types. + *

+ * The following example illustrates the use of {@link Builder} to create a + * {@link ShardingKey}: + *

+   * {@code
+   *
+   *     DataSource ds = new MyDataSource();
+   *     ShardingKey shardingKey = ds.createShardingKeyBuilder()
+   *                           .subkey("abc", JDBCType.VARCHAR)
+   *                           .subkey(94002, JDBCType.INTEGER)
+   *                           .build();
+   * }
+   * 
+ */ + public interface Builder { + + /** + * This method will be called to add a subkey into a Sharding Key object + * being built. The order in which subkey method is called is important as + * it indicates the order of placement of the subkey within the Sharding + * Key. + * + * @param subkey contains the object that needs to be part of shard sub key + * @param subkeyType sub-key data type of type java.sql.SQLType + * @return this builder object + */ + public Builder subkey(Object subkey, SqlType subkeyType); + + /** + * Returns an instance of the object defined by this builder. + * + * @return The built object + */ + public ShardingKey build(); + } + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlArray.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Identifies a type that represents an ARRAY SQL type. + * Any type to which this annotation is applied must either extend or implement + * java.util.List. Additionally the type must have at least one of the following: + *
    + *
  • a public zero-arg constructor
  • + *
  • a public constructor Constructor(int initialCapacity)
  • + *
  • a public constructor Constructor(<? super List<?>>)
  • + *
  • a public static factory method of(<? super List<?>>)
  • + *
+ * If more than one of the above is supported it is implementation dependent which + * is used. + * + * + */ +@Target({TYPE}) +@Retention(RUNTIME) +public @interface SqlArray { + public String elementSqlTypeName(); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlBlob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlBlob.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.nio.channels.AsynchronousByteChannel; +import java.util.concurrent.CompletionStage; + +/** + * A reference to a BINARY LARGE OBJECT in the attached database. + * + */ +public interface SqlBlob extends AutoCloseable { + + /** + * Return an {@link Operation} that will release the temporary resources + * associated with this {@link SqlBlob}. + * + * @return an {@link Operation} that will release the temporary resources + * associated with this {@link SqlBlob}. + */ + public Operation closeOperation(); + + @Override + public default void close() { + this.closeOperation().submit(); + } + + /** + * Return a {@link Operation} that fetches the position of this {@link SqlBlob}. + * The position is 1-based. Position 0 is immediately before the first byte in + * the {@link SqlBlob}. Position 1 is the first byte in the {@link SqlBlob}, etc. + * Position {@link length()} is the last byte in the {@link SqlBlob}. + * + * Position is between 0 and length + 1. + * + * @return a {@link Operation} that returns the position of this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public Operation getPositionOperation(); + + /** + * Get the position of this {@link SqlBlob}. The position is 1-based. Position 0 + * is immediately before the first byte in the {@link SqlBlob}. Position 1 is the + * first byte in the {@link SqlBlob}, etc. Position {@link length()} is the last + * byte in the {@link SqlBlob}. + * + * Position is between 0 and length + 1. + * + * ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java + * does? + * + * @return a future which value is the 1-based position of this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public default CompletionStage getPosition() { + return getPositionOperation().submit().getCompletionStage(); + } + + /** + * Return a {@link Operation} that fetches the length of this {@link SqlBlob}. + * + * @return a {@link Operation} that returns the length of this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public Operation lengthOperation(); + + /** + * Get the length of this {@link SqlBlob}. + * + * @return a future which value is the number of bytes in this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public default CompletionStage length() { + return lengthOperation().submit().getCompletionStage(); + } + + /** + * Return a {@link Operation} that sets the position of this {@link SqlBlob}. If + * offset exceeds the length of this {@link SqlBlob} set position to the length + + * 1 of this {@link SqlBlob}, ie one past the last byte. + * + * @param offset a non-negative number + * @return a {@link Operation} that sets the position of this {@link SqlBlob} + * @throws IllegalArgumentException if {@code offset} is less than 0 + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public Operation setPositionOperation(long offset); + + /** + * Set the position of this {@link SqlBlob}. If offset exceeds the length of this + * {@link SqlBlob} set position to the length + 1 of this {@link SqlBlob}, ie one + * past the last byte. + * + * @param offset the 1-based position to set + * @return this {@link SqlBlob} + * @throws IllegalArgumentException if offset is less than 0 + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public default SqlBlob setPosition(long offset) { + setPositionOperation(offset).submit(); + return this; + } + + /** + * Return a {@link Operation} to set the position to the beginning of the next + * occurrence of the target after the position. If there is no such occurrence + * set the position to 0. + * + * @param target a {@link SqlBlob} created by the same {@link Connection} + * containing the byte sequence to search for + * @return a {@link Operation} that locates {@code target} in this + * {@link SqlBlob} + * @throws IllegalArgumentException if {@code target} was created by some + * other {@link Connection} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public Operation locateOperation(SqlBlob target); + + /** + * Set the position to the beginning of the next occurrence of the target + * after the position. If there is no such occurrence set the position to 0. + * + * @param target the byte sequence to search for + * @return this {@link SqlBlob} + * @throws IllegalArgumentException if {@code target} was created by some + * other {@link Connection} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed + */ + public default SqlBlob locate(SqlBlob target) { + locateOperation(target).submit(); + return this; + } + + /** + * Return an {@link Operation} to set the position to the beginning of the + * next occurrence of the target after the position. If there is no such + * occurrence set the position to 0. + * + * @param target the byte sequence to search for. Not {@code null}. Captured. + * @return a {@link Operation} that locates {@code target} in this + * {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public Operation locateOperation(byte[] target); + + /** + * Set the position to the beginning of the next occurrence of the target + * after the position. If there is no such occurrence set the position to 0. + * + * @param target the byte sequence to search for + * @return this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public default SqlBlob locate(byte[] target) { + locateOperation(target).submit(); + return this; + } + + /** + * Return a {@link Operation} that truncates this {@link SqlBlob} so that the + * current position is the end of the {@link SqlBlob}. If the position is N, then + * after {@link trim()} the length is N - 1. The position is still N. This + * will fail if position is 0. + * + * @return a {@link Operation} that trims the length of this {@link SqlBlob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed or position is 0. + */ + public Operation trimOperation(); + + /** + * Truncate this {@link SqlBlob} so that the current position is the end of the + * {@link SqlBlob}. If the position is N, then after {@link trim()} the length is + * N - 1. The position is still N. This will fail if position is 0. + * + * @return this SqlBlob + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed or position is 0. + */ + public default SqlBlob trim() { + trimOperation().submit(); + return this; + } + + /** + * Return a {@link java.nio.channels.Channel} that can be used to read bytes from the + * {@link SqlBlob} beginning at the position. Reading bytes from the returned + * {@link java.nio.channels.Channel} advances the position. + * + * Each call to a read method that fetches bytes from the server creates and + * submits a virtual {@link Operation} to fetch those bytes. This virtual + * {@link Operation} is executed in sequence with other {@link Operation}s and + * may be skipped if an error occurs. + * + * @return a read-only byte {@link java.nio.channels.Channel} beginning at the position. + * @throws IllegalStateException if the {@link Connection} that created this + SqlBlob is closed. + */ + public AsynchronousByteChannel getReadChannel(); + + /** + * Return a {@link java.nio.channels.Channel} that can be used to write bytes + * to this {@link SqlBlob} beginning at the position. Bytes written overwrite + * bytes already in the {@link SqlBlob}. Writing bytes to the returned + * {@link java.nio.channels.Channel} advances the position. + * + * Each call to a write method that flushes bytes to the server creates and + * submits a virtual {@link Operation} to flush those bytes. This virtual + * {@link Operation} is executed in sequence with other {@link Operation}s and + * may be skipped if an error occurs. + * + * ISSUE: Can the app read bytes from a write + * {@link java.nio.channels.Channel}? If so then maybe remove + * {@link getReadChannel} and add a read-only flag to this method, renamed + * {@code getChannel}. + * + * @return a writable byte {@link java.nio.channels.Channel} beginning at the + * position. + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlBlob} is closed. + */ + public AsynchronousByteChannel getWriteChannel(); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlClob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlClob.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.io.Reader; +import java.io.Writer; +import java.util.concurrent.CompletionStage; + +/** + * A reference to a CHARACTER LARGE OBJECT in the attached database. + * + */ +public interface SqlClob extends AutoCloseable { + + /** + * Return an {@link Operation} that will release the temporary resources + * associated with this {@link SqlClob}. + * + * @return an {@link Operation} that will release the temporary resources + * associated with this {@link SqlClob}. + */ + public Operation closeOperation(); + + @Override + public default void close() { + this.closeOperation().submit(); + } + + /** + * Return a {@link Operation} that fetches the position of this {@link SqlClob}. + * Position 0 is immediately before the first char in the {@link SqlClob}. + * Position 1 is the first char in the {@link SqlClob}, etc. Position + * {@link length()} is the last char in the {@link SqlClob}. + * + * Position is between 0 and length + 1. + * + * @return an {@link Operation} that returns the position of this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed.; + */ + public Operation getPositionOperation(); + + /** + * Get the position of this {@link SqlClob}. Position 0 is immediately before the + * first char in the {@link SqlClob}. Position 1 is the first char in the + * {@link SqlClob}, etc. Position {@link length()} is the last char in the SqlClob. + + Position is between 0 and length + 1. + + ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java + does? + * + * @return a future which value is the position of this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public default CompletionStage getPosition() { + return getPositionOperation().submit().getCompletionStage(); + } + + /** + * Return a {@link Operation} that fetches the length of this {@link SqlClob}. + * + * @return a {@link Operation} that returns the length of this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public Operation lengthOperation(); + + /** + * Get the length of this {@link SqlClob}. + * + * @return a {@link java.util.concurrent.Future} which value is the number of + * chars in this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public default CompletionStage length() { + return lengthOperation().submit().getCompletionStage(); + } + + /** + * Return an {@link Operation} that sets the position of this {@link SqlClob}. If + * {@code offset} exceeds the length of this {@link SqlClob} set position to the + * length + 1 of this {@link SqlClob}, ie one past the last char. + * + * @param offset a non-negative number + * @return a {@link Operation} that sets the position of this {@link SqlClob} + * @throws IllegalArgumentException if {@code offset} is less than 0 + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public Operation setPositionOperation(long offset); + + /** + * Set the position of this {@link SqlClob}. If {@code offset} exceeds the length + * of this {@link SqlClob} set position to the length + 1 of this {@link SqlClob}, + * ie one past the last char. + * + * @param offset the 1-based position to set + * @return this {@link SqlClob} + * @throws IllegalArgumentException if {@code offset} is less than 0 + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public default SqlClob setPosition(long offset) { + setPositionOperation(offset).submit(); + return this; + } + + /** + * Return an {@link Operation} to set the position to the beginning of the + * next occurrence of the target after the position. If there is no such + * occurrence set the position to 0. + * + * @param target a {@link SqlClob} created by the same {@link Connection} + * containing the char sequence to search for + * @return an {@link Operation} that locates {@code target} in this + * {@link SqlClob} + * @throws IllegalArgumentException if {@code target} was created by some + * other {@link Connection} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public Operation locateOperation(SqlClob target); + + /** + * Set the position to the beginning of the next occurrence of the target + * after the position. If there is no such occurrence set the position to 0. + * + * @param target the char sequence to search for + * @return this {@link SqlClob} + * @throws IllegalArgumentException if {@code target} was created by some + * other {@link Connection} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed + */ + public default SqlClob locate(SqlClob target) { + locateOperation(target).submit(); + return this; + } + + /** + * Return an {@link Operation} to set the position to the beginning of the + * next occurrence of the target after the position. If there is no such + * occurrence set the position to 0. + * + * @param target the char sequence to search for. Not {@code null}. Captured. + * @return an {@link Operation} that locates {@code target} in this + * {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public Operation locateOperation(CharSequence target); + + /** + * Set the position to the beginning of the next occurrence of the target + * after the position. If there is no such occurrence set the position to 0. + * + * @param target the char sequence to search for + * @return this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed. + */ + public default SqlClob locate(CharSequence target) { + locateOperation(target).submit(); + return this; + } + + /** + * Return an {@link Operation} that truncates this {@link SqlClob} so that the + * current position is the end of the {@link SqlClob}. If the position is N, then + * after trim() the length is N - 1. The position is still N. This will fail + * if position is 0. + * + * @return an {@link Operation} that trims the length of this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed or position is 0. + */ + public Operation trimOperation(); + + /** + * Truncate this {@link SqlClob} so that the current position is the end of the + * {@link SqlClob}. If the position is N, then after {@link trim()} the length is + * N - 1. The position is still N. This will fail if position is 0. + * + * @return this {@link SqlClob} + * @throws IllegalStateException if the {@link Connection} that created this + * {@link SqlClob} is closed or position is 0. + */ + public default SqlClob trim() { + trimOperation().submit(); + return this; + } + + /** + * Returns a {@link Reader} for the characters in this {@link SqlClob}. + * Characters are read starting at the current position. Each character read + * advances the position by one. + * + * ISSUE: There is no character analog to + * {@link java.nio.channels.AsynchronousByteChannel}. It is trivial to + * construct a {@link java.io.Reader} from an + * {@link java.nio.channels.AsynchronousByteChannel} however. + * + * @return a Reader for the characters in this SqlClob + */ + public Reader getReader(); + + /** + * Returns a Writer for this {@link SqlClob}. Characters are written starting at + * the current position. Each character written advances the position by one. + * + * ISSUE: There is no character analog to + * {@link java.nio.channels.AsynchronousByteChannel}. It is trivial to + * construct a {@link java.io.Writer} from an + * {@link java.nio.channels.AsynchronousByteChannel} however. + * + * @return a Writer for the characters of this SqlClob + */ + public Writer getWriter(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlColumns.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlColumns.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + + +/** + * Identifies a constructor or static factory method that can be used to construct + * an instance of the containing type when the type is passed to {@link Result.ResultMap#get}. + * The method or constructor must be public. + * + * An instance of this type will be constructed by calling the factory method or + * constructor. Each element in the value of this annotation is used as a column + * identifier. The value of that column is passed to the corresponding parameter + * of the annotated method or constructor. The id argument to {@link Result.ResultMap#get} is + * prefixed to the column identifiers. + * + * The following pseudo-code describes how an instance is constructed. + * + * {@code + *
    int i = 0;
+ *   String[] columns = methodOrConstructor.getAnnotation(SqlColumns.class).value();
+ *   Object[] args = new Object[columns.length];
+ *   for (String columnName : columns)
+ *     args[i] = resultMap.get(prefix + columnName, parameterTypes[i++];
+ *   instance = methodOrConstructor.invoke(null, args);
} + * + */ +@Retention(RUNTIME) +@Target({CONSTRUCTOR, METHOD}) +public @interface SqlColumns { + + /** + * The column names corresponding to the parameters of the factory method or + * constructor to construct an instance of this type. There must be exactly one + * column name for each parameter of the annotated method or constructor. + * + * @return the column names in the order returned by the database + */ + public String[] value(); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +/** + *

+ * An exception that provides information on a database access error or other + * errors. + * + *

+ * Each SqlException provides several kinds of information: + *

    + *
  • a string describing the error. This is used as the Java Exception + * message, available via the method getMesasge. + *
  • a "SQLstate" string, which follows either the XOPEN SQLstate conventions + * or the SQL:2003 conventions. The values of the SQLState string are described + * in the appropriate spec. The DatabaseMetaData method + * getSQLStateType can be used to discover whether the driver + * returns the XOPEN type or the SQL:2003 type. + *
  • an integer error code that is specific to each vendor. Normally this + * will be the actual error code returned by the underlying database. + *
  • the causal relationship, if any for this SqlException. + *
  • the SQL string that was executing when the error occurred. + *
  • the position in the SQL string where the error was detected. + *
+ */ +public class SqlException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + // Fields + + /** + */ + private String sqlState = null; + + /** + */ + private int vendorCode = -1; + + /** + * The SQL string that was sent to the database. + */ + private String sqlString = null; + + /** + * The index of the first character in SQL where an error is detected. Zero + * based. + */ + private int position = -1; + + // Constructors + + private SqlException() { + super(); + } + + /** + * + * @param message + * @param cause + * @param sqlState + * @param vendorCode + * @param sql + * @param position + */ + public SqlException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) { + super(message, cause); + this.sqlState = sqlState; + this.vendorCode = vendorCode; + this.sqlString = sql; + this.position = position; + } + + // Methods + + /** + * Retrieves the SqlState for this SqlException object. + * + * @return the SQLState value + */ + public String getSqlState() { + return (sqlState); + } + + /** + * Retrieves the vendor-specific exception code for this + * SqlException object. + * + * @return the vendor's error code + */ + public int getVendorCode() { + return (vendorCode); + } + + /** + * Get the position. + * + * @return the index of the first character in sql where an error is detected. + * Zero based. + */ + public int getPosition() { + return position; + } + + /** + * Get the sql. + * + * @return the SQL string sent to the database + */ + public String getSqlString() { + return sqlString; + } +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlParameter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlParameter.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + + +/** + * Identifies a method the result of which will be bound to a parameter in a SQL + * statement when an instance of the containing type is passed to + * {@link ParameterizedOperation#set}. + * + * The following pseudo-code describes how an instance is used to set parameter + * values: + * + * {@code + *
    for (Method getter : annotatedMethods) {
+ *       Annotation parameter = getter.getAnnotation(SqlParameter.class);
+ *       op.set(prefix + parameter.marker(), method.invoke(instance), parameter.sqlType());
+ *   }
} + * + */ +@Retention(RUNTIME) +@Target({METHOD}) +public @interface SqlParameter { + + /** + * The marker for SQL parameter that the result of this method will be bound to. + * + * @return the name that identifies the parameter in the SQL + */ + public String marker(); + + /** + * The SQL type of the value bound to the parameter. + * Must be either the name of an enum in {@link SqlType} or the fully + * qualified name of a constant {@link SqlType}, + * for example an enum that implements that interface. + * + * @return the name of the SQL type of the value bound to the parameter + */ + public String sqlType() default ""; +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlRef.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlRef.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.util.concurrent.CompletionStage; + +/** + * + * @param + */ +public interface SqlRef { + + /** + * Return the name of SQL type of the referent of this SQL REF. + * + * ISSUE: Oracle Database JDBC driver may do a round trip for this. Is this + * that heavy in other databases? + * + * @return + */ + public String getReferentTypeName(); + + /** + * Create and return an Operation that will fetch the value of the REF from + * the database. The value of the Operation is the value of the REF. + * + * @return an Operation that will fetch the referent of this SqlRef + */ + public Operation fetchOperation(); + + /** + * Submit an Operation that will fetch the value of the REF in the database. + * + * @return a Future that will complete when the submitted Operation completes. + * The value of the Future is the value of the REF. + */ + public default CompletionStage fetch() { + return fetchOperation().submit().getCompletionStage(); + } + + /** + * Create and return an Operation that will set the value of the REF in the + * database. + * + * @param value + * @return an Operation that will store the new referent into the REF + */ + public Operation storeOperation(T value); + + /** + * Submit an Operation that will store the new value of the referent into + * the REF in the database. + * + * @param value + * @return a Future that will complete when the submitted Operation completes. + */ + public default CompletionStage store(T value) { + return storeOperation(value).submit().getCompletionStage(); + } +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * A {@link SqlException} that is used to complete an {@link Operation} when that {@link Operation} is + * skipped. If an {@link Operation} is skipped the {@link Operation} is removed from the head of + * the queue, no work is sent to the database and the {@link java.util.concurrent.CompletionStage} of that + * {@link Operation} is completed exceptionally with a {@link SqlSkippedException}. The cause of + * the {@link SqlSkippedException} is the {@link Throwable} that caused the {@link Operation} to be + * skipped, if any. + * + */ +public class SqlSkippedException extends SqlException { + + private static final long serialVersionUID = 1L; + + /** + * + * @param message + * @param cause + * @param sqlState + * @param vendorCode + * @param sql + * @param position + */ + public SqlSkippedException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) { + super(message, cause, sqlState, vendorCode, sql, position); + } +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlStruct.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlStruct.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Identifies a type that represents a STRUCT SQL type. + */ +@Target({TYPE}) +@Retention(RUNTIME) +public @interface SqlStruct { + + /** + * The SQL name of the SQL STRUCT type. + * + * @return the SQL identifier + */ + public String sqlTypeName(); + + /** + * The fields of the SQL STRUCT type. + * + * @return the fields + */ + public Field[] fields(); + + /** + * Describes a field of a SQL STRUCT type. + */ + public @interface Field { + + /** + * The name of the field in the SQL STRUCT. + * + * @return the name of the field + */ + public String sqlFieldName(); + + /** + * The name of the SQL type of the field + * + * @return the SQL type name of the field + */ + public String sqlTypeName(); + + /** + * The Java identifier corresponding to the SQL field. This identifier is + * used to determine the corresponding getter and setter for getting and + * setting the value of this field in the annotated Java type. + * + * Implementations may choose to directly access a field named with the same + * identifier or a constructor or static factory method where all of the + * formal parameters are named by @Field annotations in the applied + * @SqlStruct. + * + * @return a Java identifier + */ + public String javaFieldName(); + } +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * Remove dependence on java.sql. + */ +public interface SqlType { + + /** + * + * @return + */ + public String getName(); + + /** + * + * @return + */ + public String getVendor(); + + /** + * + * @return + */ + public Integer getVendorTypeNumber(); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType_1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType_1.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * Remove dependence on java.sql. + */ +public interface SqlType_1 { + + /** + * + * @return + */ + public String getName(); + + /** + * + * @return + */ + public String getVendor(); + + /** + * + * @return + */ + public Integer getVendorTypeNumber(); +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/StaticMultiOperation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/StaticMultiOperation.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * A multi-operation is an {@link Operation} that returns one or more results in + * addition to the result defined by the {@link Operation}. A + * {@link StaticMultiOperation} is a multi-operation where the number and types + * of the results are known in advance. Operations are executed in the order + * submitted. If an {@link Operation} is created but not submitted prior to the + * {@link StaticMultiOperation} being submitted, submitting the + * {@link StaticMultiOperation} throws {@link IllegalStateException}. + * + * @param The type of the result of this {@link Operation} + * @see DynamicMultiOperation + * @author douglas.surber + */ +public interface StaticMultiOperation extends OutOperation { + + /** + * Returns a {@link RowOperation} to process a row sequence result. The + * {@link Operation}s are executed in the order they are submitted. If a + * result is of the wrong type for the next submitted {@link Operation} the + * {@link StaticMultiOperation} is completed with + * {@link IllegalStateException}. + * + * @return a {@link RowOperation} that is part of this {@link StaticMultiOperation} + */ + public RowOperation rowOperation(); + + /** + * Returns a {@link CountOperation} to process a count result. The {@link Operation}s + * are executed in the order they are submitted. If a result is of the wrong + * type for the next submitted Operation the {@link StaticMultiOperation} is completed + * with {@link IllegalStateException}. + * + * @return a {@link CountOperation} that is part of this {@link StaticMultiOperation} + */ + public CountOperation countOperation(); + + // Covariant overrides + + @Override + public StaticMultiOperation onError(Consumer handler); + + @Override + public StaticMultiOperation apply(Function processor); + + @Override + public StaticMultiOperation outParameter(String id, SqlType type); + + @Override + public StaticMultiOperation set(String id, Object value, SqlType type); + + @Override + public StaticMultiOperation set(String id, Object value); + + @Override + public StaticMultiOperation set(String id, CompletionStage source, SqlType type); + + @Override + public StaticMultiOperation set(String id, CompletionStage source); + + @Override + public StaticMultiOperation timeout(Duration minTime); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Submission.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Submission.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +import java.util.concurrent.CompletionStage; + +/** + * The result of submitting an {@link Operation}. The {@link cancel} method of a + * {@link CompletionStage} does not cancel the {@link Operation}. This is part + * of the contract of {@link CompletionStage}. This type provides a method to + * cancel the {@link Operation}. Canceling an {@link Operation} only makes sense + * after the {@link Operation} is submitted so this type is the result of + * submitting an {@link Operation}. + * + * ISSUE: Should Operation.submit return a CompletionStage with the requirement + * that cancel attempts to cancel the database action? Conceptually this is fine. + * The concern is that it requires the implementor to implement their own + * CompletionStage or at the least subclass CompletableFuture to override + * cancel. Neither of these is trivial. + * + * @param The type of the result of the {@link Operation} that created this + * {@link Submission} + */ +public interface Submission { + + /** + * Request that the {@link Operation} not be executed or that its execution be + * aborted if already begun. This is a best effort action and may not succeed + * in preventing or aborting the execution. This method does not block. + * + * If execution is prevented the Operation is completed exceptionally with + * SkippedSqlException. If the Operation is aborted it is completed + * exceptionally with SqlException. + * + * @return a {@link java.util.concurrent.CompletionStage} that has the value + * true if the {@link Operation} is canceled. + */ + public CompletionStage cancel(); + + /** + * Returns a {@link CompletionStage} which value is the result of the + * {@link Operation}. Any actions on the returned {@link CompletionStage}, + * eg {@code completeExceptionally} or {@code cancel}, have no impact on this + * {@link Operation}. If this {@link Operation} is already completed the + * returned {@link CompletionStage} will be completed. + * + * The returned {@link CompletionStage} is completed after the Operation + * is completed. It may be completed by the same thread that completed the + * Operation or a different one. The Operation following the one that created + * this Submission begins execution when the Operation that created this + * Submission is completed. It is not required to wait for the returned + * CompletionStage to complete. [Note: this is necessary because the app can + * call this method after the Operation completes.] + * + * Each call of this method for a given {@link Operation} returns the same + * {@link CompletionStage}. + * + * @return the {@link java.util.concurrent.CompletionStage} for the result of this + * {@link Operation}. Retained. + */ + public CompletionStage getCompletionStage(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Transaction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Transaction.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.incubator.sql2; + +/** + * A mutable object that controls whether a transactionEnd Operation sends + * a database commit or a database rollback to the server. A transactionEnd + * Operation is created with a Transaction. By default a transactionEnd + * Operation requests that the database end the transaction with a commit. + * If Transaction#setRollbackOnly is called on the Transaction used to create + * the Operation prior to the Operation being executed, the Operation will + * request that the database end the transaction with a rollback. + * + * Example: + * + *
+ * {@code
+ *   Transaction t = conn.transaction();
+ *   conn.countOperation(updateSql)
+ *       .resultProcessor( count -> { if (count > 1) t.setRollbackOnly(); } )
+ *       .submit();
+ *   conn.commit(t);
+ * }
+ * + * A Transaction can not be used to create more than one endTransaction + * Operation. + * + * A Transaction is thread safe. + */ +public interface Transaction { + + /** + * Causes an endTransactionOperation created with this Transaction that is executed + * subsequent to this call to perform a rollback. If this method is not called + * prior to Operation execution the Operation will perform a commit. + * + * @return true if the call succeeded. False if the call did not succeed in + * setting the Transaction rollback only because the endTransaction + * Operation had already been executed. + */ + public boolean setRollbackOnly(); + + /** + * Returns {@code true} iff the {@link setRollbackOnly} method has been called + * on this Transaction + * + * @return {@code true} if {@link setRollbackOnly} has been called. + */ + public boolean isRollbackOnly(); + +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/TransactionOutcome.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/TransactionOutcome.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.sql2; + +/** + * Possible outcomes for a database transaction. + */ +public enum TransactionOutcome { + /** + * The outcome of the transaction is unknown. + */ + UNKNOWN, + + /** + * The transaction committed successfully. + */ + COMMIT, + + /** + * The transaction rolled back successfully. + */ + ROLLBACK; +} diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/package-info.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** + *

+ * An API for accessing and processing data stored in a data source (usually a + * relational database) using the Java™ programming language. This API + * includes a framework whereby different drivers can be installed dynamically + * to access different data sources. This API is specifically geared for passing + * SQL statements to a database though it may be used for reading and writing + * data from/to any data source that has a tabular format.

+ * + *

+ * This API differs from the API in {@code java.sql} in several ways.

+ *
    + *
  • Is asynchronous + *
  • Is geared toward high-throughput programs + *
  • Does not attempt to support every database feature + *
  • Does not attempt to abstract the database + *
  • Uses the builder pattern + *
  • Supports the fluent programming style + *
+ * + *

+ * It is worth emphasizing that this API is an alternate to the {@code java.sql} + * API, not a replacement. There are many programs that can much more readily be + * written using the {@code java.sql} API as it has many features that are not + * available in this API. For example this API provides almost no mechanism for + * getting metadata.

+ * + *

+ * This API is not an extension to the {@code java.sql} API. It an independent + * API and is used on its own without reference to java.sql.

+ * + * + *

Overview

+ * + *

+ * The core feature of this API is that it is asynchronous. No method call will + * wait for a network operation.

+ * + *

+ * Possibly blocking actions are represented as {@link Operation}s. An + * application using the API creates and submits one or more {@link Operation}s. + * The driver executes these {@link Operation}s asynchronously, reporting their + * results via {@link java.util.concurrent.CompletionStage}s. An application + * can respond to the results via the + * {@link java.util.concurrent.CompletionStage}s or via callbacks that can be + * configured on many of the {@link Operation}s or both. Creating and submitting + * {@link Operation}s is strictly non-blocking. Handling the results of possibly + * blocking {@link Operation}s is done asynchronously. No application thread + * will ever block on a call to a method in this API.

+ * + *

+ * All {@link Operation}s provide a + * {@link java.util.concurrent.CompletionStage}. The value of that + * {@link java.util.concurrent.CompletionStage} is the value of the + * {@link Operation}, set when the {@link Operation} completes. Some + * {@link Operation}s provide callbacks for processing the result of the + * {@link Operation} independent of the + * {@link java.util.concurrent.CompletionStage}. Those {@link Operation}s can + * be used for executing SQL that returns results of a specific type. For + * example SQL that returns a row sequence would be executed with a + * {@link RowOperation}. A {@link RowOperation} provides callbacks for + * processing each row and for collecting the results of processing the rows. + * Other {@link Operation}s are specialized for SQL that returns a count or that + * returns out parameters. The choice of {@link Operation} is dependent on the + * result to be processed and is independent of the particular kind of SQL + * statement.

+ * + *

+ * An {@link OperationGroup} encapsulates a group of {@link Operation}s and + * executes them using common attributes. An {@link OperationGroup} can be + * unconditional or conditional, sequential or parallel, dependent or + * independent, or any combination of these. Dependent/independent controls + * error handling. If one member of a dependent {@link OperationGroup} fails the + * remaining not-yet-executed members are completed exceptionally. If the + * {@link OperationGroup} is independent, the member {@link Operation}s are + * executed regardless of whether one or more fails.

+ * + *

+ * A {@link Connection} is itself an {@link OperationGroup} and so can be + * conditional, parallel, or independent, but by default is unconditional, + * sequential, dependent. While a {@link Connection} may be created with values + * other than the defaults, using the defaults is by far the most common case. + * The API provides convenience methods that support this case. Using these + * convenience methods is recommended in all but the most unusual circumstances. + * In particular making the {@link Connection} parallel introduces some + * challenges that would require a full understanding of the details of the API. + * It would almost certainly be better to create a parallel + * {@link OperationGroup} within the {@link Connection}.

+ * + *

+ * + * ISSUE: Should we disallow {@code Connection.parallel()}?

+ * + *

+ * The {@code java.sql} API frequently provides many ways to do the same thing. + * This API makes no attempt to do this. For those capabilities this API + * supports, it frequently defines exactly one way to do something. Doing things + * another way, for example calling methods in a non-standard order, frequently + * results in an IllegalStateException. This approach is intended to make things + * simpler for both the user and the implementor. Rather than having to + * understand complicated interactions of many different components and methods + * executed in any order, the intent is that there is only one way to do things + * so only one path must be understood or implemented. Anything off that path is + * an error. While this requires a programmer to write code in one specific way + * it makes things easier on future maintainers of the code as the code will + * conform to the standard pattern. Similarly the implementation is simplified + * as only the standard use pattern is supported.

+ * + *

+ * One way this API simplifies things in to define types as single use. Many + * types are created, configured, used once, and are then no longer usable. Many + * configuration methods can be called only once on a given instance. Once an + * instance is configured it cannot be reconfigured. Once an instance is used it + * cannot be reused. This simplifies things by eliminating the need to + * understand and implement arbitrary sequences of method calls that reconfigure + * and reuse instances. Since objects are single use there is no expectation + * that an application cache or share {@link Operation}s.

+ * + *

+ * While the user visible types are single use, it is expected that an + * implementation will cache and reuse data and {@link Object}s that are worth + * the effort. Rather than attempt to guess what an implementation should reuse + * and capture that in the API, this API leaves it entirely up to the + * implementation. Since the API specifies very little reuse, an implementation + * is free to reuse whatever is appropriate. Since the pattern of use is + * strictly enforced figuring out how to reuse objects is greatly + * simplified.

+ * + *

+ * The {@code java.sql} API provides many tools for abstracting the database, + * for enabling the user to write database independent code. This API does not. + * It is not a goal of this API to enable users to write database independent + * code. That is not to say it is not possible, just that this API does not + * provide tools to support such. Abstraction features typically impose + * performance penalties on some implementations. As this API is geared for + * high-throughput programs it avoids such abstractions rather than reduce + * performance.

+ * + *

+ * One such abstraction feature is the JDBC escape sequences. Implementing these + * features requires parsing the SQL so as to identify the escape sequences and + * then generating a new String with the vendor specific SQL corresponding to + * the escape sequence. This is an expensive operation. Further each SQL must be + * parsed whether it contains an escape sequence or not imposing the cost on all + * JDBC users, not just the ones who use escape sequences. The same is true of + * JDBC parameter markers. The SQL accepted by this API is entirely vendor + * specific, including parameter markers. There is no need for pre-processing + * prior to SQL execution substantially reducing the amount of work the + * implementation must do.

+ * + *

+ * Note: It would be a reasonable future project to develop a SQL builder API + * that creates vendor specific SQL from some more abstract representation.

+ * + *

Execution Model

+ * + *

+ * This section describes the function of a conforming implementation. It is + * not necessary for an implementation to be implemented as described only that + * the behavior be the same.

+ * + *

+ * An {@link Operation} has an action and a + * {@link java.util.concurrent.CompletionStage}. Some {@link Operation}s have + * some form of result processor.

+ * + *

+ * An {@link Operation} is executed by causing the action to be performed, + * processing the result of the action if there is a result processor, and + * completing the {@link java.util.concurrent.CompletionStage} with the result + * of the result processor if there is one or with the result of the action if + * there is no result processor. If the action or the result processing causes + * an unhandled error the {@link java.util.concurrent.CompletionStage} is + * completed exceptionally. The CompletionStage is completed asynchronously, + * as though it were created by calling an async method on + * CompletionStage. + *

+ * + *

+ * Performing the action may require one or more interactions with the database. + * These interactions may be carried out in parallel with processing the result. + * If the database result is ordered, that result is processed in that order. + * + *

+ * An {@link OperationGroup} has a collection of {@link Operation}s and + * optionally a condition. For a sequential {@link OperationGroup} + * {@link Operation}s are selected from the collection in the order they were + * submitted. For a parallel {@link OperationGroup} {@link Operation}s are + * selected from the collection in any order.

+ * + *

+ * The action of an {@link OperationGroup} is performed as follows: + *

    + *
  • + * If the {@link OperationGroup} has a condition, the value of the condition is + * retrieved. If the value is {@link Boolean#FALSE} the action is complete and + * the {@link java.util.concurrent.CompletionStage} is completed with null. If + * the value completes exceptionally the action is complete and the + * {@link java.util.concurrent.CompletionStage} is completed exceptionally + * with the same exception. If the condition value is {@link Boolean#TRUE} or + * there is no condition the {@link Operation}s in the collection are executed + * and their results processed. The action is complete when the + * {@link OperationGroup} is not held and all the {@link Operation}s have been + * executed.
  • + *
  • + * If the {@link OperationGroup} is parallel more than one {@link Operation} may + * be executed at a time.
  • + *
  • + * If the {@link OperationGroup} is dependent and an {@link Operation} completes + * exceptionally all {@link Operation}s in the collection that are yet to begin + * execution are completed exceptionally with a {@link SqlSkippedException}. The + * cause of that exception is the {@link Throwable} that caused the + * {@link Operation} to be completed exceptionally. If an {@link Operation} is + * in flight when another {@link Operation} completes exceptionally the in + * flight {@link Operation} may either be allowed to complete uninterrupted or + * it may be completed exceptionally. The {@link OperationGroup} is completed + * exceptionally with the {@link Throwable} that caused the {@link Operation} to + * complete exceptionally. Note: the {@link Operation} returned by + * {@link Connection#closeOperation} is never skipped, i.e. never completed + * exceptionally with {@link SqlSkippedException}. It is always executed.
  • + *
  • + * If the {@link OperationGroup} is independent and an {@link Operation} + * completes exceptionally all other {@link Operation}s are executed regardless. + * There is no result to be processed for an {@link Operation} that completed + * exceptionally. The {@link OperationGroup} is not completed exceptionally as + * the result of one or more {@link Operation}s completing exceptionally.
  • + *
+ * + *

+ * A {@link Connection} is a distinguished {@link OperationGroup}. A + * {@link Connection} is executed upon being submitted.

+ * + *

Transactions

+ * + *

+ * This section describes the function of a conforming implementation. It is + * not necessary for an implementation to be implemented as described only that + * the behavior be the same.

+ * + *

+ * An implementation has only limited control over transactions. SQL statements + * can start, commit, and rollback transactions without the implementation + * having any influence or even being aware. This specification only describes + * the behavior of those transaction actions that are visible to and controlled + * by the implementation, i.e. the endTransaction {@link Operation}. + * Transaction actions caused by SQL may interact with actions controlled by the + * implementation in unexpected ways.

+ * + *

+ * The creation of Operations and the subsequent execution of those Operations + * are separated in time. It is quite reasonable to determine that a transaction + * should commit after the Operation that ends the transaction is created. + * But if the execution of the transaction does not result in the expected results + * it might be necessary to rollback the transaction rather than commit it. This + * determination depends on the execution of the Operations long after the + * endTransaction Operation is created. To address this mismatch, the endTransaction Operation + * specified by this API is conditioned by a {@link Transaction}. It commits the + * transaction by default, a {@link Transaction} will cause an endTransaciton + * {@link Operation} to commit the transaction but a Transaction can be set + * to rollback the transaction at any time before the endTransaction + * {@link Operation} that references it is executed.

+ * + *

+ * An endTransaction Operation, like all Operations, is immutable once submitted. + * But an endTransaction Operation is created with a Transaction and that + * Transaction can be set to commit or rollback. A Transaction controls the + * endTransaction Operation created with it. Using this mechanism an + * error handler, result handler or other code can cause a subsequent endTransaction + * Operation to rollback instead of the default which is to commit.

+ * + *
+ * {@code
+ *   Transaction t = conn.getTransaction();
+ *   conn.countOperation(updateSql)
+ *       .resultProcessor( count -> { 
+ *           if (count > 1) t.setRollbackOnly(); 
+ *           return null; 
+ *       } )
+ *       .submit();
+ *   conn.commitMaybeRollback(t);
+ * }
+ * 
+ * + *

+ * In this example if the update SQL modifies more than one row the result + * processor will set the Transaction to rollback only. When the endTransaction + * Operation submitted by commitMaybeRollback is executed it will cause + * the transaction to rollback.

+ * + * + *

POJOs

+ * + *

Does this feature carry its weight? It is a nice ease of use feature + * for hand written code but it is not of much valuable for framework code. It + * certainly is not strictly necessary. Arguably it should be removed.

+ * + *

+ * This API supports setting and getting POJOs (Plain Old Java Objects) as + * parameter values and results. This is not a comprehensive ORM (Object + * Relational Mapping). It is just a convenience. + * + *

+ * To set parameters of a SQL statement to the values of a POJO, the type of the + * POJO must be annotated with the @SqlParameter annotation. One or more public + * getter methods must be so annotated. The @SqlParameter annotation defines the + * parameter marker base name and SQL type. The call to the + * ParameterizedOperation.set method provides the POJO itself and the parameter + * marker prefix. The implementation binds the return value of the annotated + * method to the parameter identified by the parameter marker prefix prepended + * to the parameter marker base name.

+ * + *
+ * {@code
+ *   public class Employee {
+ *     private String name;
+ *     private String department;
+ *     \@SqlParameter("name", "VARCHAR")
+ *     public String getName() { return name; }
+ *     public String getDepartement() { return department; }
+ *     \@SqlColumns("name", "dept")
+ *     public static Employee createEmployee(String name, String department) {
+ *       Employee e = new Employee();
+ *       e.name = name;
+ *       e.department = department;
+ *       return e;
+ *     }
+ *   }
+ *
+ *   conn.countOperation("insert into emp values(:emp_name, :emp_dept)")
+ *       .set("emp_", employee);
+ * }
+ * 
+ * + *

+ * The above code fragment is identical to

+ * + *
+ * {@code
+ *    conn.countOperation("insert into emp values(emp_name, emp_dept)")
+ *       .set("emp_name", employee.getName(), JdbcType.VARCHAR);
+ *       .set("emp_dept", employee.getDepartment(), JdbcType.VARCHAR)
+ * }
+ * 
+ * + *

+ * The prefix may be the empty string but may not be null. IllegalStateException + * is thrown if a parameter is set more than once either by a POJO set or a + * single value set. Implementations may attempt to bind a parameter for every + * annotated getter method. An implementation is not required to check whether + * or not there is a parameter with the specified name. It is implementation + * dependent whether an annotated getter with no corresponding parameter is an + * error or not and whether the implementation or the database detect it if it + * is an error.

+ * + *

+ * To construct a POJO from the result of an Operation the type of the POJO must + * be annotated with @SqlColumns. The annotation may be applied to a public + * static factory method, a public constructor, or one or more public setter + * methods. If applied to setters, there must be a public zero-arg constructor + * or public static zero-arg factory method. The annotation provides the base + * names for column or out parameter marker that provides the value for the + * corresponding parameter or setter method. The get method call provides the + * prefix.

+ * + *
+ * {@code
+ *     conn.rowOperation("select name, dept from emp")
+ *     .collect(Collector.of(
+ *         () -> new ArrayList(),
+ *         (l, r) -> { 
+ *             l.add(r.get("", Employee.class)); 
+ *         }
+ *         (l, r) -> l
+ *     ) )
+ * }
+ * 
+ * + *

+ * The above code fragment is identical to

+ * + *
+ * {@code
+ *     conn.rowOperation("select name, dept from emp")
+ *     .collect(Collector.of(
+ *         () -> new ArrayList(),
+ *         (l, r) -> { 
+ *             l.add(Employee.createEmployee(r.get("name", String.class), 
+ *                                         r.get("dept", String.class))); 
+ *         }
+ *         (l, r) -> l
+ *     ) )
+ * }
+ * 
+ * + *

+ * If more than one factory method, constructor, or set of setters is annotated + * it is implementation dependent which is used to construct a POJO. An + * implementation is not required to determine the best choice for any meaning + * of "best". An implementation my instead throw an exception if more than one + * alternative is annotated. If setters are annotated an implementation should + * call every annotated setter. It is implementation dependent whether it + * attempts to call a subset of the setters if all the columns named in the + * annotations are not present. In summary, best practice is to annotate exactly + * what is required and no more and to use exactly what is annotated and no more. + *

+ * + */ +package jdk.incubator.sql2; + diff -r 1f76a5f8e999 -r f06946e00a26 src/jdk.incubator.adba/share/classes/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.incubator.adba/share/classes/module-info.java Mon Apr 02 14:19:45 2018 -0400 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +module jdk.incubator.adba { + requires static transitive java.logging; + exports jdk.incubator.sql2; +}

- * If a {@code DataSourceFactoryAction} instance was specified when the JDBC factory was - * registered, its deregister method will be called - * prior to the factory being removed from the list of registered factories. - * - * @param factory the JDBC DataSourceFactory to remove - * @exception SQLException if a database access error occurs - * @throws SecurityException if a security manager exists and its - * {@code checkPermission} method denies permission to deregister a factory. - * - * @see SecurityManager#checkPermission - */ -//TODO @CallerSensitive - synchronized void deregisterDataSourceFactory(DataSourceFactory factory) { - if (factory == null) { - return; - } - - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(DEREGISTER_DATASOURCEFACTORY_PERMISSION); - } - - println("DataSourceFactoryManager.deregisterDataSourceFactory: " + factory); - - FactoryInfo aDataSourceFactory = new FactoryInfo(factory, null); - if(registeredDataSourceFactories.contains(aDataSourceFactory)) { - if (isDataSourceFactoryAllowed(factory, (Class)null)) { //TODO Reflection.getCallerClass())) { - FactoryInfo di = registeredDataSourceFactories.get(registeredDataSourceFactories.indexOf(aDataSourceFactory)); - // If a DataSourceFactoryAction was specified, Call it to notify the - // factory that it has been deregistered - if(di.action() != null) { - di.action().deregister(); - } - registeredDataSourceFactories.remove(aDataSourceFactory); - } else { - // If the caller does not have permission to load the factory then - // throw a SecurityException. - throw new SecurityException(); - } - } else { - println(" couldn't find factory to unload"); - } - } -} -/* - * Wrapper class for registered DataSourceFactories in order to not expose DataSourceFactory.equals() - * to avoid the capture of the DataSourceFactory it being compared to as it might not - * normally have access. - */ -class FactoryInfo { - - final DataSourceFactory factory; - DataSourceFactoryAction da; - FactoryInfo(DataSourceFactory factory, DataSourceFactoryAction action) { - this.factory = factory; - da = action; - } - - @Override - public boolean equals(Object other) { - return (other instanceof FactoryInfo) - && this.factory == ((FactoryInfo) other).factory; - } - - @Override - public int hashCode() { - return factory.hashCode(); - } - - @Override - public String toString() { - return ("factory[className=" + factory + "]"); - } - - DataSourceFactoryAction action() { - return da; - } -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/DynamicMultiOperation.java --- a/src/java.sql/share/classes/java/sql2/DynamicMultiOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * - * A multi-operation is an {@link Operation} that returns one or more results in - * addition to the result defined by the {@link Operation}. A {@link DynamicMultiOperation} is a - * multi-operation where the number and types of the results are determined at - * execution. - * - * NOTE: In general one way to do things is sufficient however the API provides - * two ways to handle multiple results. This way, the dynamic way, is required - * because the number and type of results cannot always be known in advance. The - * static way is also provided because it is much easier to use when the number - * and type of results is known. The improvement in ease of use outweighs the - * duplication IMO. If necessary one or the other can be eliminated. Eliminating - * dynamic reduces functionality. Eliminating static reduces ease of use in what - * I believe to be a common case. - * - * @param type of the result of this DynamicMultiOperation - */ -public interface DynamicMultiOperation extends OutOperation { - - /** - * Provides a handler for count results. The provided handler is called for - * each count result. When called the first argument is the number of results - * that preceeded the current result. The second argument is a CountOperation - * that will process the current result. This CountOperation has not been - * configured in any way nor has it been submitted. The handler configures the - * CountOperation and submits it. The count result is processed when the - * CountOperation is submitted. - * - * If this method is not called any count result is ignored. - * - * @param handler not null - * @return this DynamicMultiOperation - * @throws IllegalStateException if the CountOperation has not been submitted - * when the call to the handler returns - */ - public DynamicMultiOperation onCount(BiConsumer> handler); - - /** - * Provides a handler for row sequence results. The provided handler is called for - * each row sequence result. When called the first argument is the number of results - * that preceeded the current result. The second argument is a RowOperation - * that will process the current result. This RowOperation has not been - * configured in any way nor has it been submitted. The handler configures the - * RowOperation and submits it. The row sequence result is processed when the - * RowOperation is submitted. - * - * If this method is not called any row sequence result is ignored. - * - * @param handler - * @return This DynamicMultiOperation - * @throws IllegalStateException if the RowOperation has not been submitted - * when the call to the handler returns - */ - public DynamicMultiOperation onRows(BiConsumer> handler); - - /** - * Provides an error handler for this {@link Operation}. The provided handler - * is called for each error that occurs. When called the first argument is the - * number of results, including errors, that preceeded the current error. The - * second argument is a {@link Throwable} corresponding to the error. When the - * handler returns processing of the DynamicMultiOperation results continues. - * Only one onError method may be called. - * - * @param handler a BiConsumer that handles an error - * @return this DynamicMultiOperation - * @throws IllegalStateException if any onError method was called previously - */ - public DynamicMultiOperation onError(BiConsumer handler); - - // Covariant overrides - - /** - * Provides an error handler for this {@link Operation}. If execution of this - * {@link Operation} results in an error, before the Operation is completed, - * the handler is called with the {@link Throwable} as the argument. When the - * handler returns the {@link Operation} is completed exceptionally with the - * {@link Throwable}. - * - * @param handler - * @return this DynamicMultiOperation - * @throws IllegalStateException if any onError method was called previously - */ - @Override - public DynamicMultiOperation onError(Consumer handler); - - @Override - public DynamicMultiOperation outParameter(String id, SqlType type); - - @Override - public DynamicMultiOperation apply(Function processor); - - @Override - public DynamicMultiOperation set(String id, Object value); - - @Override - public DynamicMultiOperation set(String id, Object value, SqlType type); - - @Override - public DynamicMultiOperation set(String id, CompletionStage source); - - @Override - public DynamicMultiOperation set(String id, CompletionStage source, SqlType type); - - @Override - public DynamicMultiOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/JdbcConnectionProperty.java --- a/src/java.sql/share/classes/java/sql2/JdbcConnectionProperty.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -import java.util.function.Function; -import java.time.Duration; - -/** - * A set of {@link ConnectionProperty} commonly supported. Implementations are not - * required to support all of these properties. - * - */ -public enum JdbcConnectionProperty implements ConnectionProperty { - - /** - * - */ - CACHING(Caching.class, - v -> v instanceof Caching, - Caching.CACHED, - false), - - /** - * - */ - HOLDABILITY(Holdability.class, - v -> v instanceof Holdability, - Holdability.HOLD_OVER_COMMIT, - false), - - /** - * - */ - NETWORK_TIMEOUT(Integer.class, - v -> v instanceof Integer && ((int) v) >= 0, - Integer.MAX_VALUE, - false), - - /** - * - */ - PASSWORD(String.class, - v -> v instanceof String, - null, - true), - - /** - * - */ - READ_ONLY(Boolean.class, - v -> v instanceof Boolean, - false, - false), - - /** - * - */ - SHARDING_KEY(ShardingKey.class, - v -> v instanceof ShardingKey, - null, - false), - - /** - * - */ - SHARDING_GROUP_KEY(ShardingKey.class, - v -> v instanceof ShardingKey, - null, - false), - - /** - * - */ - CONNECT_TIMEOUT(Duration.class, - v -> v instanceof Duration && ! ((Duration)v).isNegative(), - Duration.ofSeconds(Long.MAX_VALUE), - false), - - /** - * - */ - TRANSACTION_ISOLATION(TransactionIsolation.class, - v -> v instanceof TransactionIsolation, - TransactionIsolation.READ_COMMITTED, - false), - - /** - * - */ - URL(String.class, - v -> v instanceof String, - null, - false), - - /** - * - */ - USER(String.class, - v -> v instanceof String, - null, - false); - - private final Class range; - private final Function validator; - private final Object defaultValue; - private final boolean isSensitive; - - private JdbcConnectionProperty(Class range, - Function validator, - Object value, - boolean isSensitive) { - this.range = range; - this.validator = validator; - this.defaultValue = value; - this.isSensitive = isSensitive; - } - - @Override - public Class range() { - return range; - } - - @Override - public boolean validate(Object value) { - return validator.apply(value); - } - - @Override - public Object defaultValue() { - return null; - } - - @Override - public boolean isSensitive() { - throw new UnsupportedOperationException("Not supported yet."); - } - - /** - * - */ - public enum Caching { - /** - * The returned {@link Connection} is required to be completely new and configured - * exactly as specified by the other properties. Use this with caution and - * only when absolutely necessary. Use {@link AS_NEW} instead if at all possible. - * This should be used only to work around some limitation of the database - * or the implementation. - */ - NEW, - /** - * The returned {@link Connection} has no state other than that of a new Connection - * modified as specified by the other properties. May not be strictly new - * but has the same behavior as a new {@link Connection}. The {@link Connection} may be {@link NEW}. The default. - */ - AS_NEW, - /** - * The returned {@link Connection} has the state specified by the other properties - * but may have additional state that differs from that of a new {@link Connection}. - * The {@link Connection} may be {@link AS_NEW}. - */ - CACHED; - } - - /** - * - */ - public enum TransactionIsolation { - - /** - * - */ - NONE, - - /** - * - */ - READ_COMMITTED, - - /** - * - */ - READ_UNCOMMITTED, - - /** - * - */ - REPEATABLE_READ, - - /** - * - */ - SERIALIZABLE; - } - - /** - * - */ - public enum Holdability { - - /** - * - */ - HOLD_OVER_COMMIT, - - /** - * - */ - CLOSE_AT_COMMIT; - } - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/JdbcType.java --- a/src/java.sql/share/classes/java/sql2/JdbcType.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.sql2; - -/** - * Remove dependence on java.sql. - */ -public enum JdbcType implements SqlType { - - /** - * - */ - ARRAY, - - /** - * - */ - BIGINT, - - /** - * - */ - BINARY, - - /** - * - */ - BIT, - - /** - * - */ - BOOLEAN, - - /** - * - */ - CHAR, - - /** - * - */ - CLOB, - - /** - * - */ - CURSOR, - - /** - * - */ - DATALINK, - - /** - * - */ - DATE, - - /** - * - */ - DECIMAL, - - /** - * - */ - DISTINCT, - - /** - * - */ - DOUBLE, - - /** - * - */ - FLOAT, - - /** - * - */ - INTEGER, - - /** - * - */ - JAVA_OBJECT, - - /** - * - */ - LONGNVARCHAR, - - /** - * - */ - LONGVARBINARY, - - /** - * - */ - LONGVARCHAR, - - /** - * - */ - NCHAR, - - /** - * - */ - NCLOB, - - /** - * - */ - NULL, - - /** - * - */ - NUMERIC, - - /** - * - */ - NVARCHAR, - - /** - * - */ - OTHER, - - /** - * - */ - REAL, - - /** - * - */ - REF, - - /** - * - */ - REF_CURSOR, - - /** - * - */ - ROWID, - - /** - * - */ - SMALLINT, - - /** - * - */ - SQLXML, - - /** - * - */ - STRUCT, - - /** - * - */ - TIME, - - /** - * - */ - TIMESTAMP, - - /** - * - */ - TIME_WITH_TIME_ZONE, - - /** - * - */ - TIMESTAMP_WITH_TIME_ZONE, - - /** - * - */ - TINYINT, - - /** - * - */ - VARBINARY, - - /** - * - */ - VARCHAR; - - /** - * - * @return - */ - @Override - public String getName() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * - * @return - */ - @Override - public String getVendor() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * - * @return - */ - @Override - public Integer getVendorTypeNumber() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/LocalOperation.java --- a/src/java.sql/share/classes/java/sql2/LocalOperation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.Callable; -import java.util.function.Consumer; - -/** - * An {@link Operation} that calls a user defined function when executed. Does - * not perform any database action. The result of a {@link LocalOperation} is - * the result of calling the {@link Callable}. This type allows user code to - * execute arbitrary code at particular points in the sequence of - * {@link Operation}s executed by a {@link Connection} without having to execute - * a specific database action at the same time. - * - * @param the type of the result of this {@link Operation} - */ -public interface LocalOperation extends Operation { - - /** - * Provides a result processor for this {@link Operation}. The result - * processor is called when this {@link LocalOperation} is executed. The - * result of this {@link LocalOperation} is the result of calling - * {@code callable}. - * - * @param callable the result processor called when this {@link Operation} is - * executed - * @return this {@link LocalOperation} - * @throws IllegalStateException if this method has already been called or - * this {@link Operation} has been submitted. - */ - public LocalOperation onExecution(Callable callable); - - @Override - public LocalOperation onError(Consumer handler); - - @Override - public LocalOperation timeout(Duration minTime); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/Operation.java --- a/src/java.sql/share/classes/java/sql2/Operation.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.function.Consumer; - -/** - * A description of some work to be done by the database and how to process the - * database output. An {@link Operation} is created by an - * {@link OperationGroup}, configured and submitted. If not submitted it is not - * executed. If submitted it is possibly executed according to the attributes of - * the {@link OperationGroup} that created it. - * - * Note: A {@link Connection} is an {@link OperationGroup} and so can create - * {@link Operation}s. - * - * @param the type of the result of the {@link Operation} - */ -public interface Operation { - - /** - * Provides an error handler for this {@link Operation}. If execution of this - * {@link Operation} results in an error, before the Operation is completed, - * the handler is called with the {@link Throwable} as the argument. - * - * @param handler - * @return this {@link Operation} - */ - public Operation onError(Consumer handler); - - /** - * The minimum time before this {@link Operation} might be canceled - * automatically. The default value is forever. The time is - * counted from the beginning of Operation execution. The Operation will not - * be canceled before {@code minTime} after the beginning of execution. - * Some time at least {@code minTime} after the beginning of execution, - * an attempt will be made to cancel the {@link Operation} if it has not yet - * completed. Implementations are encouraged to attempt to cancel within a - * reasonable time, though what is reasonable is implementation dependent. - * - * @param minTime minimum time to wait before attempting to cancel - * @return this Operation - * @throws IllegalArgumentException if minTime <= 0 seconds - * @throws IllegalStateException if this method is called more than once on - * this operation - */ - public Operation timeout(Duration minTime); - - /** - * Add this {@link Operation} to the tail of the {@link Operation} collection - * of the {@link Connection} that created this {@link Operation}. An - * {@link Operation} can be submitted only once. Once an {@link Operation} is - * submitted it is immutable. Any attempt to modify a submitted - * {@link Operation} will throw {@link IllegalStateException}. - * - * @return a {@link Submission} for this {@link Operation} - * @throws IllegalStateException if this method is called more than once on - * this operation - */ - public Submission submit(); - -} diff -r 1f76a5f8e999 -r f06946e00a26 src/java.sql/share/classes/java/sql2/OperationGroup.java --- a/src/java.sql/share/classes/java/sql2/OperationGroup.java Thu Mar 29 15:59:58 2018 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.sql2; - -import java.time.Duration; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.Flow; -import java.util.logging.Logger; -import java.util.stream.Collector; - -/** - * A set of {@link Operation}s that share certain properties, are managed as a - * unit, and are executed as a unit. The {@link Operation}s created by an - * {@link OperationGroup} and submitted are the member {@link Operation}s of - * that {@link OperationGroup}. - * - * An {@link OperationGroup} conceptually has a collection of member - * {@link Operation}s. When an {@link OperationGroup} is submitted it is placed - * in the collection of the {@link OperationGroup} of which it is a member. The - * member {@link OperationGroup} is executed according to the attributes of the - * {@link OperationGroup} of which it is a member. The member {@link Operation}s - * of an {@link OperationGroup} are executed according to the attributes of that - * {@link OperationGroup}. - * - * How an {@link OperationGroup} is executed depends on its attributes. - * - * If an {@link OperationGroup} has a condition and the value of that condition - * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below. - * If it is {@link Boolean#FALSE} then the {@link OperationGroup} is completed - * with the value null. If the condition completed exceptionally then the - * {@link OperationGroup} is completed exceptionally with a - * {@link SqlSkippedException} that has that exception as its cause. - * - * If the {@link OperationGroup} is sequential the member {@link Operation}s are - * executed in the order they were submitted. If it is parallel, they may be - * executed in any order including simultaneously. - * - * If an {@link OperationGroup} is dependent and a member {@link Operation} - * completes exceptionally the remaining member {@link Operation}s in the - * collection are completed exceptionally with a {@link SqlSkippedException} - * that has the initial {@link Exception} as its cause. A member - * {@link Operation} in-flight may either complete normally or be completed - * exceptionally but must complete one way or the other. [NOTE: Too strong?] - * - * If an {@link OperationGroup} is held additional member {@link Operation}s may - * be submitted after the {@link OperationGroup} is submitted. If an - * {@link OperationGroup} is not held, no additional member {@link Operation}s - * may be submitted after the {@link OperationGroup} is submitted. If an - * {@link OperationGroup} is held it will be completed only after it is released - * or if conditional and the condition is not {@link Boolean#TRUE}. If a - * {@link OperationGroup} is dependent, held, one of its member - * {@link Operation}s completed exceptionally, and its queue is empty then the - * {@link OperationGroup} is released. - * - * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is a - * intentional limitation but may be a simplification we can live with. Or not. - * - * @param The type of the result of the member {@link Operation}s - * @param The type of the collected results the member - * {@link Operation}s - */ -public interface OperationGroup extends Operation { - - /** - * Mark this {@link OperationGroup} as parallel. If this method is not called - * the {@link OperationGroup} is sequential. If an {@link OperationGroup} is - * parallel, member {@link Operation}s may be executed in any order including - * in parallel. If an {@link OperationGroup} is sequential, the default, - * member {@link Operation}s are executed strictly in the order they are - * submitted. - * - * Note: There is no covariant override of this method in {@link Connection} - * as there is only a small likelihood of needing it. - * - * @return this {@link OperationGroup} - * @throws IllegalStateException if this method has been submitted or any - * member {@link Operation}s have been created. - */ - public OperationGroup parallel(); - - /** - * Mark this {@link OperationGroup} as independent. If this method is not - * called the {@link OperationGroup} is dependent, the default. If an - * {@link OperationGroup} is independent then failure of one member - * {@link Operation} does not affect the execution of other member - * {@link Operation}s. If an {@link OperationGroup} is dependent then failure - * of one member {@link Operation} will cause all member {@link Operation}s - * remaining in the queue to be completed exceptionally with a - * {@link SqlSkippedException} with the cause set to the original exception. - * - * Note: There is no covariant override of this method in {@link Connection} - * as there is only a small likelihood of needing it. - * - * @return this {@link OperationGroup} - * @throws IllegalStateException if this {@link OperationGroup} has been - * submitted or any member {@link Operation}s have been created - */ - public OperationGroup independent(); - - /** - * Define a condition that determines whether the member {@link Operation}s of - * this {@link OperationGroup} are executed or not. If and when this - * {@link OperationGroup} is executed then if the condition argument is - * completed with {@link Boolean#TRUE} the member {@link Operation}s are - * executed. If {@link Boolean#FALSE} or if it is completed exceptionally the - * member {@link Operation}s are not executed but are removed from the queue. - * After all member {@link Operation}s have been removed from the queue this - * {@link OperationGroup} is completed with {@code null}. - * - * Note: There is no covariant override of this method in Connection as there - * is only a small likelihood of needing it. - * - * ISSUE: Should the member Operations be skipped or otherwise completed - * exceptionally? - * - * @param condition a {@link CompletionStage} the value of which determines whether - * this {@link OperationGroup} is executed or not - * @return this OperationGroup - * @throws IllegalStateException if this {@link OperationGroup} has been - * submitted or any member {@link Operation}s have been created - */ - public OperationGroup conditional(CompletionStage condition); - - /** - * Mark this {@link OperationGroup} as held. It can be executed but cannot be - * completed. A {@link OperationGroup} that is held remains in the queue even - * if all of its current member {@link Operation}s have completed. So long as - * the {@link OperationGroup} is held new member {@link Operation}s can be - * submitted. A {@link OperationGroup} that is held must be released before it - * can be completed and removed from the queue. - * - * Note: There is no covariant override of this method in Connection as there - * is only a small likelihood of needing it. - * - * ISSUE: Need a better name. - * - * @return this OperationGroup - * @throws IllegalStateException if this {@link OperationGroup} has been - * submitted - */ - public OperationGroup holdForMoreMembers(); - - /** - * Allow this {@link OperationGroup} to be completed and removed from the - * queue once all of its member {@link Operation}s have been completed. After - * this method is called no additional member {@link Operation}s can be - * submitted. Once all member {@link Operation}s have been removed from the - * queue this {@link OperationGroup} will be completed and removed from the - * queue. - * - * Calling this method when this {@link OperationGroup} is not held is a noop. - * - * Note: There is no covariant override of this method in Connection as there - * is only a small likelihood of needing it. - * - * ISSUE: Need a better name. - * - * @return this OperationGroup - * @throws IllegalStateException if this {@link OperationGroup} has been - * completed - */ - public OperationGroup releaseProhibitingMoreMembers(); - - /** - * Provides a {@link Collector} to reduce the results of the member - * {@link Operation}s.The result of this {@link OperationGroup} is the result - * of calling finisher on the final accumulated result. If the - * {@link Collector} is {@link Collector.Characteristics#UNORDERED} the member - * {@link Operation} results may be accumulated out of order. If the - * {@link Collector} is {@link Collector.Characteristics#CONCURRENT} then the - * member {@link Operation} results may be split into subsets that are reduced - * separately and then combined. If this {@link OperationGroup} is sequential, - * the characteristics of the {@link Collector} only affect how the results of - * the member {@link Operation}s are collected; the member {@link Operation}s - * are executed sequentially regardless. If this {@link OperationGroup} is - * parallel the characteristics of the {@link Collector} may influence the - * execution order of the member {@link Operation}s. - * - * @param the type of the accumulator - * @param the type of the final result - * @param c the Collector. Not null. - * @return This OperationGroup - * @throws IllegalStateException if called more than once or if this - * {@link OperationGroup} has been submitted - */ - public RowOperation collect(Collector c); - - /** - * Return a new {@link ArrayCountOperation}. - *