-// public static void setSessionSlot(Slot slot) {
-// sessionSlot = slot;
-// }
-
- //Note: Lower case ON PURPOSE. These names used to create History Messages
- public enum CRUD {
- create,read,update,delete;
- }
-
- public class PSInfo {
- private PreparedStatement ps;
- private final int size;
- private final Loader<DATA> loader;
- private final CRUD crud; // Store CRUD, because it makes a difference in Object Order, see Loader
- private final String cql;
- private final ConsistencyLevel consistency;
-
-
- /**
- * Create a PSInfo and create Prepared Statement
- *
- * @param trans
- * @param theCQL
- * @param loader
- */
- public PSInfo(TRANS trans, String theCQL, Loader<DATA> loader, ConsistencyLevel consistency) {
- this.loader = loader;
- this.consistency=consistency;
- psinfos.add(this);
-
- cql = theCQL.trim().toUpperCase();
- if(cql.startsWith("INSERT")) {
- crud = CRUD.create;
- } else if(cql.startsWith("UPDATE")) {
- crud = CRUD.update;
- } else if(cql.startsWith("DELETE")) {
- crud = CRUD.delete;
- } else {
- crud = CRUD.read;
- }
-
- int idx = 0, count=0;
- while((idx=cql.indexOf('?',idx))>=0) {
- ++idx;
- ++count;
- }
- size=count;
- }
-
- public synchronized void reset() {
- ps = null;
- }
-
- private synchronized BoundStatement ps(TransStore trans) throws APIException, IOException {
- /* From Datastax
- You should prepare only once, and cache the PreparedStatement in your application (it is thread-safe).
- If you call prepare multiple times with the same query string, the driver will log a warning.
- */
- if(ps==null) {
- TimeTaken tt = trans.start("Preparing PSInfo " + crud.toString().toUpperCase() + " on " + name,Env.SUB);
- try {
- ps = getSession(trans).prepare(cql);
- ps.setConsistencyLevel(consistency);
- } catch (DriverException e) {
- reportPerhapsReset(trans,e);
- throw e;
- } finally {
- tt.done();
- }
- }
- // BoundStatements are NOT threadsafe... need a new one each time.
- return new BoundStatement(ps);
- }
-
- /**
- * Execute a Prepared Statement by extracting from DATA object
- *
- * @param trans
- * @param text
- * @param data
- * @return
- */
- public Result<ResultSetFuture> execAsync(TRANS trans, String text, DATA data) {
- TimeTaken tt = trans.start(text, Env.REMOTE);
- try {
- return Result.ok(getSession(trans).executeAsync(
- ps(trans).bind(loader.extract(data, size, crud))));
- } catch (DriverException | APIException | IOException e) {
- AbsCassDAO.this.reportPerhapsReset(trans,e);
- return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
- } finally {
- tt.done();
- }
- }
-
- /**
- * Execute a Prepared Statement on Object[] key
- *
- * @param trans
- * @param text
- * @param objs
- * @return
- */
- public Result<ResultSetFuture> execAsync(TRANS trans, String text, Object ... objs) {
- TimeTaken tt = trans.start(text, Env.REMOTE);
- try {
- return Result.ok(getSession(trans).executeAsync(ps(trans).bind(objs)));
- } catch (DriverException | APIException | IOException e) {
- AbsCassDAO.this.reportPerhapsReset(trans,e);
- return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
- } finally {
- tt.done();
- }
- }
-
- /*
- * Note:
- *
- */
-
- /**
- * Execute a Prepared Statement by extracting from DATA object
- *
- * @param trans
- * @param text
- * @param data
- * @return
- */
- public Result<ResultSet> exec(TRANS trans, String text, DATA data) {
- TimeTaken tt = trans.start(text, Env.REMOTE);
- try {
- /*
- * "execute" (and executeAsync)
- * Executes the provided query.
- This method blocks until at least some result has been received from the database. However,
- for SELECT queries, it does not guarantee that the result has been received in full. But it
- does guarantee that some response has been received from the database, and in particular
- guarantee that if the request is invalid, an exception will be thrown by this method.
-
- Parameters:
- statement - the CQL query to execute (that can be any Statement).
- Returns:
- the result of the query. That result will never be null but can be empty (and will
- be for any non SELECT query).
- */
- return Result.ok(getSession(trans).execute(
- ps(trans).bind(loader.extract(data, size, crud))));
- } catch (DriverException | APIException | IOException e) {
- AbsCassDAO.this.reportPerhapsReset(trans,e);
- return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
- } finally {
- tt.done();
- }
- }
-
- /**
- * Execute a Prepared Statement on Object[] key
- *
- * @param trans
- * @param text
- * @param objs
- * @return
- */
- public Result<ResultSet> exec(TRANS trans, String text, Object ... objs) {
- TimeTaken tt = trans.start(text, Env.REMOTE);
- try {
- return Result.ok(getSession(trans).execute(ps(trans).bind(objs)));
- } catch (DriverException | APIException | IOException e) {
- AbsCassDAO.this.reportPerhapsReset(trans,e);
- return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
- } finally {
- tt.done();
- }
- }
-
- /**
- * Read the Data from Cassandra given a Prepared Statement (defined by the
- * DAO Instance)
- *
- * This is common behavior among all DAOs.
- * @throws DAOException
- */
- public Result<List<DATA>> read(TRANS trans, String text, Object[] key) {
- TimeTaken tt = trans.start(text,Env.REMOTE);
-
- ResultSet rs;
- try {
- rs = getSession(trans).execute(key==null?ps(trans):ps(trans).bind(key));
-/// TEST CODE for Exception
-// boolean force = true;
-// if(force) {
-// Map<InetSocketAddress, Throwable> misa = new HashMap<InetSocketAddress,Throwable>();
-// //misa.put(new InetSocketAddress(444),new Exception("no host was tried"));
-// misa.put(new InetSocketAddress(444),new Exception("Connection has been closed"));
-// throw new com.datastax.driver.core.exceptions.NoHostAvailableException(misa);
-//// throw new com.datastax.driver.core.exceptions.AuthenticationException(new InetSocketAddress(9999),"no host was tried");
-// }
+// public static void setSessionSlot(Slot slot) {
+// sessionSlot = slot;
+// }
+
+ //Note: Lower case ON PURPOSE. These names used to create History Messages
+ public enum CRUD {
+ create,read,update,delete;
+ }
+
+ public class PSInfo {
+ private PreparedStatement ps;
+ private final int size;
+ private final Loader<DATA> loader;
+ private final CRUD crud; // Store CRUD, because it makes a difference in Object Order, see Loader
+ private final String cql;
+ private final ConsistencyLevel consistency;
+
+
+ /**
+ * Create a PSInfo and create Prepared Statement
+ *
+ * @param trans
+ * @param theCQL
+ * @param loader
+ */
+ public PSInfo(TRANS trans, String theCQL, Loader<DATA> loader, ConsistencyLevel consistency) {
+ this.loader = loader;
+ this.consistency=consistency;
+ psinfos.add(this);
+
+ cql = theCQL.trim().toUpperCase();
+ if (cql.startsWith("INSERT")) {
+ crud = CRUD.create;
+ } else if (cql.startsWith("UPDATE")) {
+ crud = CRUD.update;
+ } else if (cql.startsWith("DELETE")) {
+ crud = CRUD.delete;
+ } else {
+ crud = CRUD.read;
+ }
+
+ int idx = 0, count=0;
+ while ((idx=cql.indexOf('?',idx))>=0) {
+ ++idx;
+ ++count;
+ }
+ size=count;
+ }
+
+ public synchronized void reset() {
+ ps = null;
+ }
+
+ private synchronized BoundStatement ps(TransStore trans) throws APIException, IOException {
+ /* From Datastax
+ You should prepare only once, and cache the PreparedStatement in your application (it is thread-safe).
+ If you call prepare multiple times with the same query string, the driver will log a warning.
+ */
+ if (ps==null) {
+ TimeTaken tt = trans.start("Preparing PSInfo " + crud.toString().toUpperCase() + " on " + name,Env.SUB);
+ try {
+ ps = getSession(trans).prepare(cql);
+ ps.setConsistencyLevel(consistency);
+ } catch (DriverException e) {
+ reportPerhapsReset(trans,e);
+ throw e;
+ } finally {
+ tt.done();
+ }
+ }
+ // BoundStatements are NOT threadsafe... need a new one each time.
+ return new BoundStatement(ps);
+ }
+
+ /**
+ * Execute a Prepared Statement by extracting from DATA object
+ *
+ * @param trans
+ * @param text
+ * @param data
+ * @return
+ */
+ public Result<ResultSetFuture> execAsync(TRANS trans, String text, DATA data) {
+ TimeTaken tt = trans.start(text, Env.REMOTE);
+ try {
+ return Result.ok(getSession(trans).executeAsync(
+ ps(trans).bind(loader.extract(data, size, crud))));
+ } catch (DriverException | APIException | IOException e) {
+ AbsCassDAO.this.reportPerhapsReset(trans,e);
+ return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
+ } finally {
+ tt.done();
+ }
+ }
+
+ /**
+ * Execute a Prepared Statement on Object[] key
+ *
+ * @param trans
+ * @param text
+ * @param objs
+ * @return
+ */
+ public Result<ResultSetFuture> execAsync(TRANS trans, String text, Object ... objs) {
+ TimeTaken tt = trans.start(text, Env.REMOTE);
+ try {
+ return Result.ok(getSession(trans).executeAsync(ps(trans).bind(objs)));
+ } catch (DriverException | APIException | IOException e) {
+ AbsCassDAO.this.reportPerhapsReset(trans,e);
+ return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
+ } finally {
+ tt.done();
+ }
+ }
+
+ /*
+ * Note:
+ *
+ */
+
+ /**
+ * Execute a Prepared Statement by extracting from DATA object
+ *
+ * @param trans
+ * @param text
+ * @param data
+ * @return
+ */
+ public Result<ResultSet> exec(TRANS trans, String text, DATA data) {
+ TimeTaken tt = trans.start(text, Env.REMOTE);
+ try {
+ /*
+ * "execute" (and executeAsync)
+ * Executes the provided query.
+ This method blocks until at least some result has been received from the database. However,
+ for SELECT queries, it does not guarantee that the result has been received in full. But it
+ does guarantee that some response has been received from the database, and in particular
+ guarantee that if the request is invalid, an exception will be thrown by this method.
+
+ Parameters:
+ statement - the CQL query to execute (that can be any Statement).
+ Returns:
+ the result of the query. That result will never be null but can be empty (and will
+ be for any non SELECT query).
+ */
+ return Result.ok(getSession(trans).execute(
+ ps(trans).bind(loader.extract(data, size, crud))));
+ } catch (DriverException | APIException | IOException e) {
+ AbsCassDAO.this.reportPerhapsReset(trans,e);
+ return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
+ } finally {
+ tt.done();
+ }
+ }
+
+ /**
+ * Execute a Prepared Statement on Object[] key
+ *
+ * @param trans
+ * @param text
+ * @param objs
+ * @return
+ */
+ public Result<ResultSet> exec(TRANS trans, String text, Object ... objs) {
+ TimeTaken tt = trans.start(text, Env.REMOTE);
+ try {
+ return Result.ok(getSession(trans).execute(ps(trans).bind(objs)));
+ } catch (DriverException | APIException | IOException e) {
+ AbsCassDAO.this.reportPerhapsReset(trans,e);
+ return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);
+ } finally {
+ tt.done();
+ }
+ }
+
+ /**
+ * Read the Data from Cassandra given a Prepared Statement (defined by the
+ * DAO Instance)
+ *
+ * This is common behavior among all DAOs.
+ * @throws DAOException
+ */
+ public Result<List<DATA>> read(TRANS trans, String text, Object[] key) {
+ TimeTaken tt = trans.start(text,Env.REMOTE);
+
+ ResultSet rs;
+ try {
+ rs = getSession(trans).execute(key==null?ps(trans):ps(trans).bind(key));
+/// TEST CODE for Exception
+// boolean force = true;
+// if (force) {
+// Map<InetSocketAddress, Throwable> misa = new HashMap<>();
+// //misa.put(new InetSocketAddress(444),new Exception("no host was tried"));
+// misa.put(new InetSocketAddress(444),new Exception("Connection has been closed"));
+// throw new com.datastax.driver.core.exceptions.NoHostAvailableException(misa);
+//// throw new com.datastax.driver.core.exceptions.AuthenticationException(new InetSocketAddress(9999),"no host was tried");
+// }