From c376934c2d7a2b6d6de641ca6402d848f82bca9c Mon Sep 17 00:00:00 2001 From: Mike Jarmy Date: Tue, 16 Jul 2024 08:14:51 -0400 Subject: [PATCH] sql: update documentation (#52) * sql: update config.props * sql: clean up StatementPeer * sql: update pod documentation * sql: update ChangeLog * sql: update documentation --- etc/sql/config.props | 7 +++-- src/doc/docIntro/doc/ChangeLog.fandoc | 3 ++ src/sql/java/StatementPeer.java | 10 +++++-- src/sql/pod.fandoc | 42 ++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/etc/sql/config.props b/etc/sql/config.props index 44a59ee0a..a4ef800c7 100644 --- a/etc/sql/config.props +++ b/etc/sql/config.props @@ -7,10 +7,13 @@ // Java JDBC drivers; these are java classnames separated by a comma // which are loaded into the VM using Class.forName on startup -// java.drivers=com.mysql.jdbc.Driver +// java.drivers=com.mysql.cj.jdbc.Driver // test setup -test.uri=jdbc:postgresql://localhost:5432/postgres +test.uri=jdbc:mysql://localhost:3306/fantest test.username=fantest test.password=fantest +// Uncomment this line to revert old "@@" escape behavior. +// See https://github.com/fantom-lang/fantom/pull/51 +// deprecatedEscape=true diff --git a/src/doc/docIntro/doc/ChangeLog.fandoc b/src/doc/docIntro/doc/ChangeLog.fandoc index 868eee446..918e86e2b 100644 --- a/src/doc/docIntro/doc/ChangeLog.fandoc +++ b/src/doc/docIntro/doc/ChangeLog.fandoc @@ -11,9 +11,12 @@ - Rewrite fant in Fantom as new util::TestRunner class - Add dom::Storage.keys to iterate all keys - Add new SqlConnPool API +- Add support for postgres TEXT[] type - Support for static once methods - StrBuf.addRange - Add double checked locking into ClassType.java reflect and finish +- Add sql escape syntax for "@" and "\" +- Deprecate old, undocumented sql escape syntax (This is a breaking change) *Build 1.0.80 (23 Apr 2024)* - New ECMA class-based JavaScript design diff --git a/src/sql/java/StatementPeer.java b/src/sql/java/StatementPeer.java index b71c879b4..6974bfef6 100644 --- a/src/sql/java/StatementPeer.java +++ b/src/sql/java/StatementPeer.java @@ -29,6 +29,9 @@ public void init(Statement self) java.sql.Statement.RETURN_GENERATED_KEYS : java.sql.Statement.NO_GENERATED_KEYS; + // are we using the old deprecated escape "@@foo" + String depEsc = self.typeof().pod().config("deprecatedEscape"); + this.isDeprecatedEscape = ((depEsc != null) && depEsc.equals("true")); } public Statement prepare(Statement self) @@ -43,9 +46,7 @@ public Statement prepare(Statement self) if ((self.sql.indexOf('@') != -1) || (self.sql.indexOf('\\') != -1)) { // Check for deprecated escape: "@@foo" - String depEsc = self.typeof().pod().config("deprecatedEscape"); - - if ((depEsc != null) && depEsc.equals("true")) + if (isDeprecatedEscape) { DeprecatedTokenizer t = DeprecatedTokenizer.make(self.sql); this.translated = t.sql; @@ -420,8 +421,11 @@ private void createStatement(Statement self) private java.sql.Statement stmt; private Map paramMap; private int limit = 0; // limit field value + + // These are set during init(): private boolean isInsert; // does sql contain insert keyword private boolean isAutoKeys; // isInsert and connector supports auto-gen keys private int autoKeyMode; // JDBC constant for auto-gen keys + private boolean isDeprecatedEscape; // are we using the old deprecated escape "@@foo" } diff --git a/src/sql/pod.fandoc b/src/sql/pod.fandoc index 6f6200f52..dd40b2856 100644 --- a/src/sql/pod.fandoc +++ b/src/sql/pod.fandoc @@ -52,6 +52,10 @@ Connections are managed by the `sql::SqlConn` class. To open and close connecti to the database, simply call the [SqlConn.open]`sql::SqlConn.open` and [SqlConn.close]`sql::SqlConn.close` methods. +A pool of Connections is managed by the `sql::SqlConnPool` class. To use a +connection created by this pool, use the +[SqlConnPool.execute]`sql::SqlConnPool.execute` method. + Connections in Java [#java] =========================== When running in a Java VM, Fantom uses JDBC under the covers. Using @@ -62,13 +66,13 @@ the JVM: the system class path. The best place to stick it is in the "jre/lib/ext" directory. You can use 'fan -version' to locate your JRE directory. For MySQL the driver is packaged -up as something like "mysql-connector-java-5.0.6-bin.jar". +up as something like "mysql-connector-j-9.0.0.jar" or "postgresql-42.7.3.jar". 2. Ensure the JDBC class is loaded into memory. The simplest way to preload the class is to ensure the classname is defined in "etc/sql/config.props" : - java.drivers=com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver + java.drivers=java.drivers=com.mysql.cj.jdbc.Driver,org.postgresql.Driver 3. Open a SqlConn instance using the JDBC URL: @@ -85,8 +89,8 @@ Statements [#statements] ************************ SQL statements are created using the [SqlConn.sql]`sql::SqlConn.sql` method. After a statement has been created, it can be executed immediately -by calling [execute]`sql::Statement.execute` or it can be prepared for later -execution by calling [prepare]`sql::Statement.prepare`. +by calling [Statement.execute]`sql::Statement.execute` or it can be prepared for later +execution by calling [Statement.prepare]`sql::Statement.prepare`. For example, to create a table in MySQL: db.sql("create table Books ( @@ -108,6 +112,33 @@ parameters. addBook.execute(["title":"The Jungle Book", "author":"Rudyard Kipling", "year":1894]) addBook.execute(["title":"Captains Courageous", "author":"Rudyard Kipling", "year":1897]) +Escape Sequences +================ +When calling [Statement.prepare]`sql::Statement.prepare`, the strings '\@' and +'\\' in the Statement's SQL are escaped into '@' and '\' respectively. + +Examples: + +In mysql, to refer to the user variable @v1 in a prepared Statement: + + select name, \@v1 from foo where id = @id; + +In postgres, to use the JSONB operator @> in a prepared Statement: + + select * from foo where data \@> '{"x": 99}'::jsonb; + +There is an old, undocumented syntax for referring to mysql user variables, +using the escape sequence '@@v1', for example: + + select name, @@v1 from foo where id = @id; + +This syntax is deprecated and is no longer supported by default. If you have +existing code that uses this undocumented feature, you must add the following +entry to "etc/sql/config.props": + + deprecatedEscape=true + + Queries [#queries] ****************** The result of an SQL query is always a relational table described @@ -154,6 +185,7 @@ The following type specifies the mapping of SQL types to Fantom types: CHAR sys::Str VARCHAR sys::Str LONGVARCHAR sys::Str + TEXT[] sys::List of sys::Str BIT sys::Bool @@ -177,5 +209,7 @@ The following type specifies the mapping of SQL types to Fantom types: DATE sys::Date TIME sys::Time + BYTEA sys::Buf + catch-all sys::Str