Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.

public final class DataSource

  1. Object
  2. DataSource

A pool of connections to ONE database, whichever engine that database is.

DbPool pools SQLite and only SQLite – it opens connections from a file path, so there is nowhere to put a host, a user or a password. That left the server engines with the advice to share a single Database and accept that every handler queues behind whichever exchange is on the socket, because a Database over PostgreSQL or MySQL owns one wire connection and synchronizes every operation on it.

Queueing is the right default for a server whose database is a local file. It is the wrong one for a server whose database is a machine across a network that is perfectly happy to run eight statements at once: there the single connection is not a safety property, it is the bottleneck. This is the same pool for all three, so which engine is behind it stops being a question the application’s structure has to answer.

DataSource db = DataSource.open("postgres://user:pw@db.internal/app");
List rows = db.query("SELECT id, title FROM notes WHERE author = ?",
        new Object[] {author});

The convenience methods above borrow a connection, run one statement and release it, which is what a handler wants: it is the borrow held ACROSS unrelated work that empties a pool. inTransaction is the form for several statements that have to be one, and it holds exactly one connection for exactly the body.

Connections are opened lazily except the first, which is opened by open so that a wrong URL, an unreachable host or a refused password fails at start-up rather than on the first request that needed the database.

An in-memory SQLite database is pooled at size one, and a configuration asking for more is REFUSED rather than quietly reduced. Each connection to “:memory:” gets its OWN private database, so a pool of them hands successive requests different empty databases – the one case where a bigger pool is not slower but wrong, and a setting worth reporting rather than ignoring.

Nested types

interface DataSource.WorkA unit of work run against one borrowed connection.

Methods

public static DataSource open(String url) throws IOExceptionA pool of the default size for whatever engine url names.
public static DataSource open(String url, int size) throws IOExceptionA pool of size connections; 0 takes the default for the engine.
public static DataSource open(String url, int size, int busyTimeoutMillis, long borrowTimeoutMillis) throws IOExceptionThe general form.
public static DataSource fromConfig(Config config) throws IOExceptionThe pool a Config describes, which is the one a server normally wants: the URL comes from the deployment rather than from the source.
public static DataSource of(Database db) throws IOExceptionA pool of one around a connection somebody else opened, for code that has a Database already and wants the pooled API around it.
public synchronized Database borrow() throws IOExceptionTakes a connection, blocking until one is free.
public synchronized void release(Database db)Returns a borrowed connection to the pool.
public Object withConnection(DataSource.Work body) throws ExceptionBorrows a connection, runs body, and returns it however body ends.
public Object inTransaction(DataSource.Work body) throws ExceptionOne transaction on one borrowed connection.
public int execute(String sql, Object[] params) throws IOExceptionOne statement on a borrowed connection.
public List query(String sql, Object[] params) throws IOExceptionOne query on a borrowed connection.
public Map queryOne(String sql, Object[] params) throws IOExceptionOne query that returns at most one row, on a borrowed connection.
public long insert(String sql, Object[] params, String idColumn) throws IOExceptionOne INSERT on a borrowed connection, answering the key the database generated.
public Dialect dialect()How this pool’s engine spells things.
public int getMaxSize()How many connections this pool may hold.
public synchronized int getOpenCount()How many are open right now, borrowed or idle.
public synchronized int getIdleCount()How many are open and free right now.
public synchronized void close()Closes every connection.
public String toString()Returns a string representation of the object.

Inherited methods

Method details

open

public static DataSource open(String url) throws IOException
A pool of the default size for whatever engine url names.

open

public static DataSource open(String url, int size) throws IOException
A pool of size connections; 0 takes the default for the engine.

open

public static DataSource open(String url, int size, int busyTimeoutMillis, long borrowTimeoutMillis) throws IOException
The general form.

Parameters

url String
Not documented.
size int
how many connections at most; 0 for the engine’s default
busyTimeoutMillis int
how long SQLite waits on a locked database; ignored by the server engines, which have no such setting
borrowTimeoutMillis long
how long a borrow waits for a free connection before failing; 0 waits forever

fromConfig

public static DataSource fromConfig(Config config) throws IOException

The pool a Config describes, which is the one a server normally wants: the URL comes from the deployment rather than from the source.

With no URL configured at all this answers an in-memory SQLite database on a development profile, and refuses on any other. Defaulting silently in production is how a service comes up healthy, serves requests, writes everything into a database inside its own process and loses all of it at the next deploy.

of

public static DataSource of(Database db) throws IOException

A pool of one around a connection somebody else opened, for code that has a Database already and wants the pooled API around it.

The connection is NOT closed by close: it belongs to whoever opened it.

borrow

public synchronized Database borrow() throws IOException
Takes a connection, blocking until one is free. Release it in a finally, or prefer the methods that cannot leak one.

release

public synchronized void release(Database db)
Returns a borrowed connection to the pool.

withConnection

public Object withConnection(DataSource.Work body) throws Exception
Borrows a connection, runs body, and returns it however body ends.

Throws

Exception

inTransaction

public Object inTransaction(DataSource.Work body) throws Exception

One transaction on one borrowed connection.

Everything the body does through the Database it is handed is inside that transaction. Anything it does through THIS pool is not: that borrows a second connection, which the database sees as another session entirely, and on SQLite it will simply block against the write lock the first one holds.

Throws

Exception

execute

public int execute(String sql, Object[] params) throws IOException
One statement on a borrowed connection.

query

public List query(String sql, Object[] params) throws IOException
One query on a borrowed connection.

queryOne

public Map queryOne(String sql, Object[] params) throws IOException
One query that returns at most one row, on a borrowed connection.

insert

public long insert(String sql, Object[] params, String idColumn) throws IOException

One INSERT on a borrowed connection, answering the key the database generated.

The connection is held across the insert AND the question that reads the key back, which is what makes the answer this insert’s on the engines where the key is a property of the session – SQLite’s last_insert_rowid and MySQL’s LAST_INSERT_ID both answer for the connection they are asked on. A pooled insert that released between the two would read whatever the next borrower had done.

dialect

public Dialect dialect()
How this pool’s engine spells things. See Dialect.

getMaxSize

public int getMaxSize()
How many connections this pool may hold.

getOpenCount

public synchronized int getOpenCount()
How many are open right now, borrowed or idle.

getIdleCount

public synchronized int getIdleCount()
How many are open and free right now.

close

public synchronized void close()
Closes every connection. Borrowed ones are closed as they come back.

toString

public String toString()
Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@’, and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + ‘@’ + Integer.toHexString(hashCode())