src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java
branchJDK-8188051-branch
changeset 56824 62e92191354d
parent 56797 fb523d4d9185
child 56997 c9cbac2979fb
equal deleted inserted replaced
56823:6ba0dbf6a75f 56824:62e92191354d
    26 package jdk.incubator.sql2;
    26 package jdk.incubator.sql2;
    27 
    27 
    28 import java.util.LinkedList;
    28 import java.util.LinkedList;
    29 import java.util.List;
    29 import java.util.List;
    30 import java.util.function.Consumer;
    30 import java.util.function.Consumer;
       
    31 import java.util.function.LongConsumer;
    31 
    32 
    32 /**
    33 /**
    33  * Uses the builder pattern to get a {@link Connection}. A {@link DataSource#getConnection}
    34  * Uses the builder pattern to get a {@link Session}. A {@link DataSource#getSession}
    34  * method is provided as a convenience.
    35  * method is provided as a convenience.
    35  * 
    36  * 
    36  * Implementations must be thread safe.
    37  * Implementations must be thread safe.
    37  */
    38  */
    38 public interface DataSource
    39 public interface DataSource
    46    * ISSUE: Probably need property(DataSourceProperty prop, Object value).
    47    * ISSUE: Probably need property(DataSourceProperty prop, Object value).
    47    */
    48    */
    48   public interface Builder {
    49   public interface Builder {
    49 
    50 
    50     /**
    51     /**
    51      * A convenience method for setting the {@link AdbaConnectionProperty#URL}.
    52      * Specify a property and its value for the built {@link DataSource}.
    52      *
    53      *
    53      * @param url the value to be set for {@link AdbaConnectionProperty#URL}
    54      * @param p {@link DataSourceProperty} to set. Not {@code null}.
    54      * @return this {@link Builder}
    55      * @param v value for the property
    55      * @see connectionProperty
    56      * @return this {@link Builder}
       
    57      * @throws IllegalArgumentException if {@code p.validate(v)} does not return
       
    58      * true, if this method has already been called with the property
       
    59      * {@code p}, or the implementation does not support the 
       
    60      * {@link DataSourceProperty}.
       
    61      */
       
    62     public Builder property(DataSourceProperty p, Object v);
       
    63 
       
    64     /**
       
    65      * A convenience method for setting the {@link AdbaSessionProperty#URL}.
       
    66      *
       
    67      * @param url the value to be set for {@link AdbaSessionProperty#URL}
       
    68      * @return this {@link Builder}
       
    69      * @see sessionProperty
    56      */
    70      */
    57     public default Builder url(String url) {
    71     public default Builder url(String url) {
    58       return connectionProperty(AdbaConnectionProperty.URL, url);
    72       return sessionProperty(AdbaSessionProperty.URL, url);
    59     }
    73     }
    60 
    74 
    61     /**
    75     /**
    62      * A convenience method for setting the {@link AdbaConnectionProperty#USER}.
    76      * A convenience method for setting the {@link AdbaSessionProperty#USER}.
    63      *
    77      *
    64      * @param name the value to be set for {@link AdbaConnectionProperty#USER}
    78      * @param name the value to be set for {@link AdbaSessionProperty#USER}
    65      * @return this {@link Builder}
    79      * @return this {@link Builder}
    66      * @see connectionProperty
    80      * @see sessionProperty
    67      */
    81      */
    68     public default Builder username(String name) {
    82     public default Builder username(String name) {
    69       return connectionProperty(AdbaConnectionProperty.USER, name);
    83       return sessionProperty(AdbaSessionProperty.USER, name);
    70     }
    84     }
    71 
    85 
    72     /**
    86     /**
    73      * A convenience method for setting the {@link AdbaConnectionProperty#PASSWORD}.
    87      * A convenience method for setting the {@link AdbaSessionProperty#PASSWORD}.
    74      *
    88      *
    75      * @param password the value to be set for {@link AdbaConnectionProperty#PASSWORD}
    89      * @param password the value to be set for {@link AdbaSessionProperty#PASSWORD}
    76      * @return this {@link Builder}
    90      * @return this {@link Builder}
    77      * @see connectionProperty
    91      * @see sessionProperty
    78      */
    92      */
    79     public default Builder password(String password) {
    93     public default Builder password(String password) {
    80       return connectionProperty(AdbaConnectionProperty.PASSWORD, password);
    94       return sessionProperty(AdbaSessionProperty.PASSWORD, password);
    81     }
    95     }
    82     
    96     
    83     /**
    97     /**
    84      * Specify the value of a {@link Connection} property that will be set by default on
    98      * Specify the value of a {@link Session} property that will be set by default on
    85      * all {@link Connection}s produced by this {@link DataSource}. A different value can be set
    99      * all {@link Session}s produced by this {@link DataSource}. A different value can be set
    86      * for a particular {@link Connection} via {@link Connection.Builder#property}.
   100      * for a particular {@link Session} via {@link Session.Builder#property}.
    87      *
   101      *
    88      * @param property the {@link ConnectionProperty} to be set. May not be {@code null}.
   102      * @param property the {@link SessionProperty} to be set. May not be {@code null}.
    89      * @param value the value to be set for {@code property}
   103      * @param value the value to be set for {@code property}
    90      * @return this {@link Builder}
   104      * @return this {@link Builder}
    91      * @throws IllegalArgumentException if {@code property.validate(value)} does not
   105      * @throws IllegalArgumentException if {@code property.validate(value)} does not
    92      * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if
   106      * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if
    93      * this property has been specified previously to this method or
   107      * this property has been specified previously to this method or
    94      * {@link connectionProperty} or {@link registerConnectionProperty}.
   108      * {@link sessionProperty} or {@link registerSessionProperty}.
    95      * @throws IllegalStateException if {@link build} has previously been called.
   109      * @throws IllegalStateException if {@link build} has previously been called.
    96      */
   110      */
    97     public Builder defaultConnectionProperty(ConnectionProperty property, Object value);
   111     public Builder defaultSessionProperty(SessionProperty property, Object value);
    98 
   112 
    99     /**
   113     /**
   100      * Specify the value of a {@link Connection} property that will be set on
   114      * Specify the value of a {@link Session} property that will be set on
   101      * all {@link Connection}s produced by the built {@link DataSource}.
   115      * all {@link Session}s produced by the built {@link DataSource}.
   102      * Attempting to set a different value via
   116      * Attempting to set a different value via
   103      * {@link Connection.Builder#property} will throw
   117      * {@link Session.Builder#property} will throw
   104      * {@link IllegalArgumentException}.
   118      * {@link IllegalArgumentException}.
   105      *
   119      *
   106      * @param property the {@link ConnectionProperty} to set. May not be
   120      * @param property the {@link SessionProperty} to set. May not be
   107      * {@code null}.
   121      * {@code null}.
   108      * @param value the value to set as the default for {@code property}
   122      * @param value the value to set as the default for {@code property}
   109      * @return this {@link Builder}
   123      * @return this {@link Builder}
   110      * @throws IllegalArgumentException if {@code property.validate(value)} does
   124      * @throws IllegalArgumentException if {@code property.validate(value)} does
   111      * not return {@code true}. If it throws an {@link Exception} that
   125      * not return {@code true}. If it throws an {@link Exception} that
   112      * {@link Exception} is the cause. Or if this property has been specified
   126      * {@link Exception} is the cause. Or if this property has been specified
   113      * previously to this method or {@link defaultConnectionProperty} or
   127      * previously to this method or {@link defaultSessionProperty} or
   114      * {@link registerConnectionProperty}.
   128      * {@link registerSessionProperty}.
   115      * @throws IllegalStateException if {@link build} has previously been
   129      * @throws IllegalStateException if {@link build} has previously been
   116      * called.
   130      * called.
   117      */
   131      */
   118     public Builder connectionProperty(ConnectionProperty property, Object value);
   132     public Builder sessionProperty(SessionProperty property, Object value);
   119 
   133 
   120     /**
   134     /**
   121      * Make a user defined property known to the implementation. One reason to
   135      * Make a user defined property known to the implementation. One reason to
   122      * do this is so the default value of the property will be used. If the
   136      * do this is so the default value of the property will be used. If the
   123      * {@link DataSource} doesn't know about the property then it cannot know to
   137      * {@link DataSource} doesn't know about the property then it cannot know to
   124      * set the default value. Convenience method.
   138      * set the default value. Convenience method.
   125      *
   139      *
   126      * @param property the {@link ConnectionProperty} to make known. May not be
   140      * @param property the {@link SessionProperty} to make known. May not be
   127      * {@code null}.
   141      * {@code null}.
   128      * @return this Builder
   142      * @return this Builder
   129      * @throws IllegalArgumentException if this property has been specified
   143      * @throws IllegalArgumentException if this property has been specified
   130      * previously to this method or {@link connectionProperty} or
   144      * previously to this method or {@link sessionProperty} or
   131      * {@link defaultConnectionProperty}.
   145      * {@link defaultSessionProperty}.
   132      * @throws IllegalStateException if {@link build} has previously been
   146      * @throws IllegalStateException if {@link build} has previously been
   133      * called.
   147      * called.
   134      */
   148      */
   135     public default Builder registerConnectionProperty(ConnectionProperty property) {
   149     public default Builder registerSessionProperty(SessionProperty property) {
   136       return defaultConnectionProperty(property, property.defaultValue());
   150       return defaultSessionProperty(property, property.defaultValue());
   137     }
   151     }
   138 
   152 
   139     /**
   153     /**
   140      * Provide a method that the built {@link DataSource} will call to control the
   154      * Provide a method that the built {@link DataSource} will call to control the
   141      * rate of {@link DataSource#connectOperation} submissions. The built
   155      * rate of {@link Session} creations. The built
   142      * {@link DataSource} will call {@code request} with a positive argument
   156      * {@link DataSource} will call {@code request} with a positive argument
   143      * when the {@link DataSource} is able to accept more
   157      * when the {@link DataSource} is able to accept more calls to
   144      * {@link DataSource#connectOperation} submissions. The difference between
   158      * {@link DataSource#builder}. The difference between
   145      * the sum of all arguments passed to {@code request} and the number of
   159      * the sum of all arguments passed to {@code request} and the number of
   146      * calls to {@link DataSource#builder} is the
   160      * calls to {@link DataSource#builder} is the
   147      * <i>demand</i>. The demand must always be non-negative. If a call is made to
   161      * <i>demand</i>. The demand must always be non-negative. If a call is made to
   148      * {@link DataSource#builder} that would make the demand negative that call 
   162      * {@link DataSource#builder} that would make the demand negative, that call 
   149      * throws {@link IllegalStateException}. If {@code requestHook} is not called,
   163      * throws {@link IllegalStateException}. If {@code requestHook} is not called,
   150      * the demand is defined to be infinite.
   164      * the demand is defined to be infinite.
   151      * 
   165      * 
   152      * <p>
   166      * <p>
   153      * An implementation may choose to delay detection of insufficient demand. 
   167      * Since the user thread is never blocked, a user thread could in theory 
   154      * Instead of checking when {@link DataSource#builder} is called an 
   168      * create, attach, use, and close {@link Session}s faster than the underlying
   155      * implementation may choose to check at some later point in Connection 
   169      * implementation can process the submitted work. At some point work would
   156      * creation such as {@link Connection.Builder.build} or 
   170      * start timing out or Java would run out of memory to store the queued
   157      * {@code Connection#connectOperation().submit()} or even later. In any case
   171      * {@link Operation}s. This is a poor way address the issue. This method 
   158      * an implementation must throw IllegalStateException before allocating
   172      * allows user code to get feedback from the {@link DataSource} as to whether
   159      * or waiting to allocate scarce resources if the demand is negative.</p>
   173      * the {@link DataSource} can accept more work.
       
   174      * </p>
   160      *
   175      *
   161      * @param request accepts calls to increase the demand. Not null.
   176      * @param request accepts calls to increase the demand. Not null.
   162      * @return this {@link Builder}
   177      * @return this {@link Builder}
   163      * @throws IllegalStateException if this method has been called previously
   178      * @throws IllegalStateException if this method has been called previously
   164      */
   179      */
   165     public Builder requestHook(Consumer<Long> request);
   180     public Builder requestHook(LongConsumer request);
   166 
   181 
   167     /**
   182     /**
   168      * Return a DataSource configured as specified. 
   183      * Return a DataSource configured as specified. 
   169      *
   184      *
   170      * @return a configured {@link DataSource}. Not {@code null}.
   185      * @return a configured {@link DataSource}. Not {@code null}.
   173      */
   188      */
   174     public DataSource build();
   189     public DataSource build();
   175   }
   190   }
   176 
   191 
   177   /**
   192   /**
   178    * Returns a {@link Connection} builder. By default that builder will return
   193    * Returns a {@link Session} builder. By default that builder will return
   179    * {@link Connection}s with the {@code ConnectionProperty}s specified when creating this
   194    * {@link Session}s with the {@code SessionProperty}s specified when creating this
   180    * DataSource. Default and unspecified {@link ConnectionProperty}s can be set with
   195    * DataSource. Default and unspecified {@link SessionProperty}s can be set with
   181    * the returned builder.
   196    * the returned builder.
   182    *
   197    *
   183    * @return a new {@link Connection} builder. Not {@code null}.
   198    * @return a new {@link Session} builder. Not {@code null}.
   184    * @throws IllegalStateException if this {@link DataSource} is closed
   199    * @throws IllegalStateException if this {@link DataSource} is closed
   185    */
   200    */
   186   public Connection.Builder builder();
   201   public Session.Builder builder();
   187 
   202 
   188   /**
   203   /**
   189    * Returns a {@link Connection} that has a submitted connect {@link Operation}. Convenience
   204    * Returns a {@link Session} that has a submitted attach {@link Operation}. Convenience
   190    * method for use with try with resources.
   205    * method for use with try with resources.
   191    *
   206    *
   192    * @return a {@link Connection}
   207    * @return a {@link Session}
   193    * @throws IllegalStateException if this {@link DataSource} is closed
   208    * @throws IllegalStateException if this {@link DataSource} is closed
   194    */
   209    */
   195   public default Connection getConnection() {
   210   public default Session getSession() {
   196     return builder().build().connect();
   211     return builder().build().attach();
   197   }
   212   }
   198 
   213 
   199   /**
   214   /**
   200    * Returns a {@link Connection} that has a submitted connect {@link Operation} with an error
   215    * Returns a {@link Session} that has a submitted attach {@link Operation} with an error
   201    * handler. Convenience method for use with try with resources. The error
   216    * handler. Convenience method for use with try with resources. The error
   202    * handle handles errors in the connect {@link Operation}.
   217    * handle handles errors in the attach {@link Operation}.
   203    *
   218    *
   204    * @param handler for errors in the connect {@link Operation}
   219    * @param handler for errors in the attach {@link Operation}
   205    * @return a {@link Connection}
   220    * @return a {@link Session}
   206    * @throws IllegalStateException if this {@link DataSource} is closed
   221    * @throws IllegalStateException if this {@link DataSource} is closed
   207    */
   222    */
   208   public default Connection getConnection(Consumer<Throwable> handler) {
   223   public default Session getSession(Consumer<Throwable> handler) {
   209     return builder().build().connect(handler);
   224     return builder().build().attach(handler);
   210   }
   225   }
   211   
   226   
   212   /**
   227   /**
   213    * Translates a SQL string from the format specified by the format argument
   228    * Translates a SQL string from the format specified by the format argument
   214    * to a format that can be used to create {@link Operation}s for the {@link Connection}s
   229    * to a format that can be used to create {@link Operation}s for the {@link Session}s
   215    * provided by this {@link DataSource}. 
   230    * provided by this {@link DataSource}. 
   216    * 
   231    * 
   217    * ISSUE: Just an idea
   232    * ISSUE: Just an idea
   218    * 
   233    * 
   219    * @param format not {@code null}
   234    * @param format not {@code null}