I have the following code for a simple key value store for binary data:
BeginPackage["keyValueStore`"];
{open, insert, get, close};
Begin["`Private`"];
Needs["DatabaseLink`"];
open[] := (
$connection = OpenSQLConnection[JDBC["SQLite(Memory)",""]];
SQLCreateTable[$connection, SQLTable["data"], {
SQLColumn["key", "DataTypeName" -> "TEXT"],
SQLColumn["value", "DataTypeName" -> "BLOB", "Nullable" -> True]
}];
);
insert[key_, data_] := SQLInsert[$connection,
"data", {"key", "value"}, {key, SQLBinary[data]}];
get[key_] := Replace[
SQLSelect[$connection, "data", "value", SQLColumn["key"] == key],
{{SQLBinary[data_]}} :> data
];
close[] := CloseSQLConnection[$connection];
End[];
EndPackage[];
which one could use like this:
open[];
insert["one", {1, 2, 3}]
get["one"]
close[];
if you try this, you will find that inserting data will not work but throw a message like:
DatabaseLink`JDBC::error: "Illegal value: DatabaseLink`SQLBinary[{1, 2, 3}]"
now I can repair that by either doing:
BeginPackage["keyValueStore`",{"DatabaseLink`"}]
(which I don't want) or by replacing SQLBinary with Symbol["SQLBinary"] in the code. Both seem to repair a behavior considering the context of SQLBinary that I would consider a bug, but maybe just don't understand correctly what is going on. Would anyone agree that this is not as one would expect and should be repaired? Or can someone enlighten me why this is what I should expect?
Needsto before theBegin? – Szabolcs Sep 12 '17 at 09:12DatabaseLink`SQLBinary[{1, 2, 3}]illegal or what? What should be the context ofSQLBinary? – Kuba Sep 12 '17 at 09:29Databaselink`is on$ContextPathor thatSQLBinaryis created in the current$Context... – Albert Retey Sep 12 '17 at 09:35SQLBinary[{1,2,3}]would be correct input givenSQLBinaryis in the correct contex. When INeeds["DatabaseLink`"]then there is aSQLBinaryin theDatabaselink`context so that would be the context forSQLBinarythat I would expect to work, but obviously in the above situation it doesn't... – Albert Retey Sep 12 '17 at 09:41$ContextPath. The reason could be that there's some string-to-code translation somewhere in the package. Maybe through J/Link? A workaround could be to temporarily add"DatabaseLink`"to the context path while your functions is being evaluated (usingInheritedBlock). But this still bothers me ... – Szabolcs Sep 12 '17 at 09:57SQLStatementProcessor.java, lines 23 and 266. What happens is that the Mathematica expression is converted to a string, and this string is checked for correctness by some Java code. If DatabaseLink is in the context path, the string will be"SQLBinary". If it is not, it will be"DatabaseLink`SQLBinary". This doesn't match the pre-defined stringSYM_SQLBINARY = "SQLBinary", so the Java code throws an exception. – Szabolcs Sep 12 '17 at 10:07BeginPackageto import dependencies. The problem is that someone who will you your package may now know it. – Kuba Sep 12 '17 at 10:19