diff --git a/build.gradle b/build.gradle index 8b7d39bd..54266819 100755 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ repositories { //---------------------------------------------------------------- // The Project version -version = '4.1.0' +version = '4.1.3' // Setup java compilation version sourceCompatibility = 1.8 diff --git a/src/main/java/picoded/dstack/connector/jsql/JSql_Base.java b/src/main/java/picoded/dstack/connector/jsql/JSql_Base.java index ba61f0b6..f95646d0 100755 --- a/src/main/java/picoded/dstack/connector/jsql/JSql_Base.java +++ b/src/main/java/picoded/dstack/connector/jsql/JSql_Base.java @@ -130,6 +130,16 @@ protected PreparedStatement prepareSqlStatment(Connection sqlConn, String qStrin ps.setDouble(pt + 1, (Double) argObj); } else if (Float.class.isInstance(argObj)) { ps.setFloat(pt + 1, (Float) argObj); + } else if (Boolean.class.isInstance(argObj)){ + boolean bValue = (Boolean) argObj; + // note that due to a bug in dstack before 26 Aug 2024, + // ... all boolean values were stored as json (Core_DataType.JSON, 31) + // ...thus entry is stored with the values: nVl = NULL, sVL = null, tVl = "true" or "false" + // ... thus, for boolean, we need to query against tVl to support legacy values + // ... this bug has been fixed in newer versions of dstack... + // ... where the entry is stored with the values: nVl = 1 or 0, sVL = "true" or "false", tVl = "true" or "false" + ps.setString(pt + 1, bValue ? "true" : "false"); + // ps.setBoolean(pt + 1, (Boolean) argObj); // this does not work, bc this transforms the value to 1/0 } else if (Date.class.isInstance(argObj)) { java.sql.Date sqlDate = new java.sql.Date(((Date) argObj).getTime()); ps.setDate(pt + 1, sqlDate); diff --git a/src/main/java/picoded/dstack/core/Core_DataType.java b/src/main/java/picoded/dstack/core/Core_DataType.java index 671fe2bf..126ad89d 100755 --- a/src/main/java/picoded/dstack/core/Core_DataType.java +++ b/src/main/java/picoded/dstack/core/Core_DataType.java @@ -59,7 +59,12 @@ public enum Core_DataType { * String type **/ STRING(25), - + + /** + * Boolean type + */ + BOOLEAN(26), + // // Storage types // diff --git a/src/main/java/picoded/dstack/jsql/JSql_DataObjectMapUtil.java b/src/main/java/picoded/dstack/jsql/JSql_DataObjectMapUtil.java index e47e5901..37c6b36c 100755 --- a/src/main/java/picoded/dstack/jsql/JSql_DataObjectMapUtil.java +++ b/src/main/java/picoded/dstack/jsql/JSql_DataObjectMapUtil.java @@ -193,7 +193,15 @@ public static Object[] valueToValueTypeSet(Object value) { return valueTypeSet(Core_DataType.STRING.getValue(), null, shortenStringValue(value), value.toString(), EmptyArray.BYTE); } - + + // Boolean type support + // - stores nVl as 1 or 0 + // - store sVl and tVl as the string value : "true" or "false" + if(value instanceof Boolean){ + return valueTypeSet(Core_DataType.BOOLEAN.getValue(), ((Boolean) value) ? 1 : 0, value.toString(), value.toString(), + EmptyArray.BYTE); + } + // Binary type support if (value instanceof byte[]) { return valueTypeSet(Core_DataType.BINARY.getValue(), null, null, null, (byte[]) value); @@ -251,14 +259,36 @@ protected static Object extractNonArrayValueFromPos(JSqlResult r, int pos) { } else if (baseType == Core_DataType.TEXT.getValue()) { // Text return r.get("tVl").getString(pos); } - + + // + // Boolean value support + // + if(baseType == Core_DataType.BOOLEAN.getValue()){ + String tVl = r.getString("tVl"); + if(tVl.equalsIgnoreCase("true")){ + return true; + } + if(tVl.equalsIgnoreCase("false")){ + return false; + } + // get the value from nVl + int nVl = r.getInt("nVl"); + if(nVl == 1){ + return true; + } + if(nVl == 0){ + return false; + } + throw new JSqlException("Invalid boolean value: tVl=" + tVl + ", nVl=" + nVl); + } + // // Binary value // if (baseType == Core_DataType.BINARY.getValue()) { // Older base64 stroage format // return (Base64.getDecoder().decode((String) (r.get("tVl").get(pos)))); - + Object rawValue = r.get("rVl").get(pos); if (rawValue instanceof java.sql.Blob) { java.sql.Blob blobData = (java.sql.Blob) rawValue; diff --git a/src/main/java/picoded/dstack/jsql/JSql_DataObjectMap_QueryBuilder.java b/src/main/java/picoded/dstack/jsql/JSql_DataObjectMap_QueryBuilder.java index 8974eda2..cda5549a 100755 --- a/src/main/java/picoded/dstack/jsql/JSql_DataObjectMap_QueryBuilder.java +++ b/src/main/java/picoded/dstack/jsql/JSql_DataObjectMap_QueryBuilder.java @@ -921,6 +921,16 @@ private Query dynamicTableQueryRewrite( // "(" + collumnTableAlias + ".sVl IS NULL OR " + replacement.toString() + ")"); } } + } else if (argObj instanceof Boolean) { + // note that due to a bug in dstack before 26 Aug 2024, + // ... all boolean values were stored as json (Core_DataType.JSON, 31) + // ...thus entry is stored with the values: nVl = NULL, sVL = null, tVl = "true" or "false" + // ... thus, for boolean, we need to query against tVl to support legacy values + // ... this bug has been fixed in newer versions of dstack... + // ... where the entry is stored with the values: nVl = 1 or 0, sVL = "true" or "false", tVl = "true" or "false" + replacement = QueryFilter.basicQueryFromTokens(queryArgMap, collumnTableAlias + + ".tVl", toReplace.operatorSymbol(), ":" + toReplace.argumentName() // + ); } // Unprocessed arg type diff --git a/src/main/java/picoded/dstack/mongodb/MongoDB_FileWorkspaceMap.java b/src/main/java/picoded/dstack/mongodb/MongoDB_FileWorkspaceMap.java index e52e4c49..d27bb3a6 100755 --- a/src/main/java/picoded/dstack/mongodb/MongoDB_FileWorkspaceMap.java +++ b/src/main/java/picoded/dstack/mongodb/MongoDB_FileWorkspaceMap.java @@ -677,7 +677,15 @@ public byte[] backend_fileRead(String oid, String filepath) { **/ public InputStream backend_fileReadInputStream(String oid, String filepath) { try { - return gridFSBucket.openDownloadStream(oid + "/" + filepath); + + // id of the file to download + return gridFSBucket.openDownloadStream( + // name of the file to download + oid + "/" + filepath, + // set the revision number to -1 to download the latest copy of the file + new GridFSDownloadOptions().revision(-1) + ); + } catch (Exception e) { if (e.getMessage().toLowerCase().indexOf("no file found") >= 0) { // Does nothing if no file is found