Class Definer
public class Definer
extends java.lang.Object
Mechanism for defining Query, Update and valueOf classes.
This is the main class you'll use to interact with Wrapd, at least to start with.
This class turns SQL query definitions into Java methods, like having an assistant who writes code for you.
Use it like this:
public class Definitions extends Definer { public Definitions(Database database, String codeDirectory, String packageSpec) { super(database, codeDirectory, packageSpec); } void generate() throws Throwable { // Delete everything in the target directory. purgeTarget(); // Generate definition for table ABC. defineTable("$$ABC"); // Generate definition for a query called JoinABCXYZWhere. defineQuery("JoinABCXYZWhere", "SELECT * FROM $$ABC, $$XYZ WHERE x = a AND x > {lower} AND x < {higher}", 2, 5); // Generate a definition for a query called ValueOfXYZz that returns the value of the first // column of the first row of the result. (If there isn't one, the returned Option type is empty.) defineValueOf("ValueOfXYZz", "SELECT z FROM $$XYZ WHERE x = {xValue}", 33); // Emit the above definitions in a single class called DatabaseAbstractionLayer, with // methods for each definition above. emitDatabaseAbstractionLayer("DatabaseAbstractionLayer"); } // Run the above queries; generate code to run them again via Java methods. public static void main(String[] args) throws Throwable { var database = new Database(...); var codeDirectory = "../path/to/code/in/project"; var codePackage = "pkg.code.the"; var sqlDefinitions = new Definitions(database, codeDirectory, codePackage); sqlDefinitions.generate(); System.out.println("OK: Queries are ready."); } }Then take a look in the "../path/to/code/in/project" directory to see what it's generated. In particular, in this example you'll want to look at DatabaseAbstractionLayer.java. You'll see that it contains method definitions corresponding to the generated queries.
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Definer.DefineQueryResult
The result of Query generation.static class
Definer.DefineValueOfResult
The result of ValueOf generation. -
Constructor Summary
-
Method Summary
Modifier and Type Method Description void
define(java.lang.String yamlFileName)
Given the filespec of a YAML query definition file, run it to define queries.Definer.DefineQueryResult
defineQuery(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args)
Define a Tuple type, and a Query class with query methods.Definer.DefineQueryResult
defineQueryForTable(java.lang.String queryName, java.lang.String tableName, java.lang.String sqlText, java.lang.Object... args)
Define a Tuple type, and a Query class with query methods.Definer.DefineQueryResult
defineTable(java.lang.String tableName)
Define a Tuple type, and Query class that has an insert(...) and an update(...) for the specified table.Definer.DefineQueryResult
defineTable(java.lang.String tableName, java.lang.String whereClause, java.lang.Object... args)
Define a Tuple type, and a Query class with insert(...) and update(...) methods for the specified table.java.util.Collection<SQLTypeGenerator.Method>
defineUpdate(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args)
Define an Update class with update(...) methods.Definer.DefineValueOfResult
defineValueOf(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args)
Define a ValueOf class with methods that return the first column of the first row.void
emitDatabaseAbstractionLayer(java.lang.String newClassName)
Create a new class that provides to invoke all the methods defined using this Definer.java.util.Map<java.lang.String,java.util.Collection<SQLTypeGenerator.Method>>
getMethods()
Get all the classes and their methods defined by using this Definer.void
purgeTarget()
Prior to generating new code, purge everything in the package-specified subdirectory of the code directory.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Constructor Details
-
Definer
Create a Definer, given a Database, the directory where generated class definitions will be stored, and their package.- Parameters:
database
- DatabasecodeDirectory
- Directory for generated class definitions.packageSpec
- The package, in dotted notation, to which the Tuple belongs.
-
-
Method Details
-
getMethods
Get all the classes and their methods defined by using this Definer.- Returns:
- Collection of method definitions for each defined class.
-
emitDatabaseAbstractionLayer
public void emitDatabaseAbstractionLayer(java.lang.String newClassName)Create a new class that provides to invoke all the methods defined using this Definer. Note that generated methods will always have (at least) a lower-case first character, in keeping with Java convention. That means query names with an upper-case first character, e.g., ClearABC, will emit a method called clearABC.- Parameters:
newClassName
- Name of the generated database abstraction layer class definition.
-
purgeTarget
public void purgeTarget()Prior to generating new code, purge everything in the package-specified subdirectory of the code directory. This avoids possible build errors that may result from the build pipeline attempting to compile outdated code. It's an optional operation in case the target contains content that needs to be kept, though arguably it shouldn't be used that way. -
defineQueryForTable
public Definer.DefineQueryResult defineQueryForTable(java.lang.String queryName, java.lang.String tableName, java.lang.String sqlText, java.lang.Object... args) throws java.lang.ThrowableDefine a Tuple type, and a Query class with query methods.- Parameters:
queryName
- Name of query. Should be unique.tableName
- Name of table the generated Tuple maps to. Null if not mapped to a table. If not null, the Tuple type will have an insert(...) and an update(...) for the specified table.sqlText
- SQL query text. Parameters may be specified as ? or {name}. If {name} is used, it will appear as a corresponding Java method name. If ? is used, it will be named pn, where n is a unique number in the given definition. Use getSQLText() after generate() to obtain final SQL query text with all {name} converted to ? for subsequent evaluation.args
- Arguments that specify parameter type(s) and allow query to succeed.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
defineQuery
public Definer.DefineQueryResult defineQuery(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args) throws java.lang.ThrowableDefine a Tuple type, and a Query class with query methods.- Parameters:
queryName
- Name of query. Should be unique.sqlText
- SQL query text. Parameters may be specified as ? or {name}. If {name} is used, it will appear as a corresponding Java method name. If ? is used, it will be named pn, where n is a unique number in the given definition. Use getSQLText() after generate() to obtain final SQL query text with all {name} converted to ? for subsequent evaluation.args
- Arguments that specify parameter type(s) and allow query to succeed.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
defineUpdate
public java.util.Collection<SQLTypeGenerator.Method> defineUpdate(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args) throws java.lang.ThrowableDefine an Update class with update(...) methods. WARNING: This will test the query by running it. Hope you're not doing this on a production database!- Parameters:
queryName
- Name of update query. Should be unique.sqlText
- SQL query text. Parameters may be specified as ? or {name}. If {name} is used, it will appear as a corresponding Java method name. If ? is used, it will be named pn, where n is a unique number in the given definition. Use getSQLText() after generate() to obtain final SQL query text with all {name} converted to ? for subsequent evaluation.args
- Arguments that specify parameter type(s) and allow update query to succeed.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
defineTable
public Definer.DefineQueryResult defineTable(java.lang.String tableName, java.lang.String whereClause, java.lang.Object... args) throws java.lang.ThrowableDefine a Tuple type, and a Query class with insert(...) and update(...) methods for the specified table. The Query is SELECT * FROM tableName WHERE whereClause.- Parameters:
tableName
- Name of the table, optionally including $$. Note that the generated class will have the same name as the table without $$ and with the first character converted to upper case. E.g., a table name of $$blah will be represented by a class named Blah.whereClause
- The WHERE clause without the 'WHERE' keyword. Parameters may be specified as ? or {name}. If {name} is used, it will appear as a corresponding Java method name. If ? is used, it will be named pn, where n is a unique number in the given definition. Use getSQLText() after generate() to obtain final SQL query text with all {name} converted to ? for subsequent evaluation.args
- Arguments that specify parameter type(s) and allow query to succeed.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
defineTable
public Definer.DefineQueryResult defineTable(java.lang.String tableName) throws java.lang.ThrowableDefine a Tuple type, and Query class that has an insert(...) and an update(...) for the specified table. The Query is SELECT * FROM tableName.- Parameters:
tableName
- Name of the table, optionally including $$.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
defineValueOf
public Definer.DefineValueOfResult defineValueOf(java.lang.String queryName, java.lang.String sqlText, java.lang.Object... args) throws java.lang.ThrowableDefine a ValueOf class with methods that return the first column of the first row.- Parameters:
queryName
- Name of valueOf query. Should be unique.sqlText
- SQL query text. Parameters may be specified as ? or {name}. If {name} is used, it will appear as a corresponding Java method name. If ? is used, it will be named pn, where n is a unique number in the given definition. Use getSQLText() after generate() to obtain final SQL query text with all {name} converted to ? for subsequent evaluation. For optimum performance, should have one and only one column and return one row.args
- Arguments that specify parameter type(s) and allow query to succeed.- Returns:
- Result of generation.
- Throws:
java.lang.Throwable
- Error.
-
define
public void define(java.lang.String yamlFileName) throws java.lang.ThrowableGiven the filespec of a YAML query definition file, run it to define queries.
The file actually specifies a series of method invocations of methods defined in the Definer class.
An example YAML query definition file -- which might be called testqueries.yaml -- looks like this:
defineTable: $$abc: $$xyz: - x = {xvalue} - [22] defineQueryForTable: SelectABCWhere2: - $$abc - SELECT * FROM $$abc WHERE a = {aVal} - [22] defineQuery: JoinABCXYZ2: - SELECT * FROM $$abc, $$xyz WHERE x = a JoinABCXYZWhere2: - SELECT * FROM $$abc, $$xyz WHERE x = a AND x > {lower} AND x < {higher} - [2, 5] defineUpdate: ClearABC2: - DELETE FROM $$abc ClearXYZ2: - DELETE FROM $$xyz ClearABCWhere2: - DELETE FROM $$abc WHERE a = {aValue} - [3] defineValueOf: ValueOfABCb2: - SELECT b FROM $$abc ValueOfXYZz2: - SELECT z FROM $$xyz WHERE x = {xValue} - [33]
The file is defined as a set of keys, where each key is the name of a Definer method. E.g., defineQueryForTable, defineQuery, defineUpdate, defineValueOf, etc. The define method may be specified here to include other YAML query definition files within a YAML query definition file.
Within each key, query names are defined. E.g, JoinABCXYZ2 and JoinABCXYZWhere2 are defineQuery queries.
Each query name specifies an array, where the first element must be the SQL text associated with the query name. E.g., the query named by JoinABCXYZWhere2 is:
SELECT * FROM $$abc, $$xyz WHERE x = a AND x > {lower} AND x < {higher}
If the query defines parameters, test arguments must be provided. Then they are the second array element, which is itself an array. For the above query, the test argument array is [2, 5]. Since the arguments are positional corresponding to the appearance of the parameter names, 2 will be the value passed to lower and 5 will be the value passed to higher.
- Parameters:
yamlFileName
- YAML query definition file.- Throws:
java.lang.Throwable
- Error.
-