[image: MailTag] Hey Lukas, Thanks for pointing out that, will take care of those improvements.
Regarding the language, I'm using Groovy 2.5 with jdk 8. Thanks! Federico On Mon, Sep 10, 2018 at 5:11 AM Lukas Eder <[email protected]> wrote: > Thanks a lot for sharing this. Will definitely be useful to others. > > What language is this? Xtend? Groovy? > > I do see something worth improving. Note you can wrap your JDBC Connection > using DSL.using(Connection) to get a jOOQ DSLContext and run statements > there. It will help with auto-closing of resources, which you omitted. If > the code generation is large, then omitting closing all result sets and > prepared statements could definitely cause issues. > > Hope this helps, > Lukas > > On Fri, Sep 7, 2018 at 6:46 PM Federico Piazza <[email protected]> > wrote: > >> [image: MailTag] >> Hi Lukas, >> >> Thanks a lot. I have followed your suggestion and could come up with >> something (I hope useful). I still remain to make the stuff about the >> forced types, but I can move forward for the moment. >> >> I'll post my solution for other people might find it useful since I >> struggled a lot against this. By the way, if you see something very bad, >> please feel free to suggest any tip. >> >> Here is the code that is generating my custom enums out of my db: >> >> package com.ctgcommon.jooq >> >> import org.jooq.codegen.JavaGenerator >> import org.jooq.codegen.JavaWriter >> import org.jooq.meta.Database >> import org.jooq.meta.SchemaDefinition >> import org.jooq.meta.TableDefinition >> import org.slf4j.Logger >> import org.slf4j.LoggerFactory >> >> import java.sql.ResultSet >> >> class EnumGenerator extends JavaGenerator { >> private static final String ENUMS_SCHEMA = "enums" >> >> private static final Logger log = >> LoggerFactory.getLogger(EnumGenerator.class) >> >> @Override >> void generateSchema(SchemaDefinition schema) { >> // Apply custom logic only for `enums` schema. Others schema has >> regular generation >> if (schema.name != ENUMS_SCHEMA) { >> super.generateSchema(schema) >> return >> } >> >> log.info("Generating custom enums") >> >> log.info("----------------------------------------------------------") >> >> Database db = schema.database >> >> db.getTables(schema).each { TableDefinition table -> >> // Prepare enum name from snake_case to CamelCase >> String enumName = table.name.replaceAll('_([a-z])') { >> it[1].capitalize() }.capitalize() >> >> JavaWriter out = newJavaWriter(new >> File(getFile(schema).getParentFile(), "${enumName}.java")) >> log.info("Generating custom enum: {}.java for table '{}'", >> enumName, table.name) >> >> printPackage(out, schema) >> >> out.println("public enum $enumName {") >> >> ResultSet rs = db.connection.prepareStatement("SELECT * FROM >> ${schema}.\"${table.name}\"").executeQuery() >> while (rs.next()) { >> String name = rs.getString('name'), >> description = rs.getString('description'), >> s = rs.isLast() ? ";" : "," >> >> // Generate enum entry >> out.tab(1).println("$name(\"$description\")$s") >> } >> >> out.println(""" >> | private final String description; >> | >> | private $enumName(String description) { >> | this.description = description; >> | } >> |} >> """.stripMargin()) >> >> closeJavaWriter(out) >> } >> >> >> log.info("----------------------------------------------------------") >> super.generateSchema(schema) >> } >> } >> >> >> Hope to help. >> Federico >> >> On Wed, Sep 5, 2018 at 11:50 PM Lukas Eder <[email protected]> wrote: >> >>> Hi Federico, >>> >>> Thanks for your feedback. Glad you got your generator working with Maven. >>> >>> Indeed, there was support for generating custom enums from tables in >>> jOOQ 2.x. The problem wasn't strictly complexity, but the fact that there >>> are about 20 different ways how one could want to generate such enums. The >>> 2.x feature simply didn't respond to all those requirements. >>> >>> I'm guessing you need help to figure out how to generate your own >>> classes right now. Your EnumGenerator should now override one of the >>> generate() methods (e.g. generate(Database) or generateCatalog(...) or >>> generateSchema(...)), which should call the super implementation, and then >>> proceed to generating your enums. Here, you're entirely on your own, which >>> means you have complete freedom in how to design your class. >>> >>> Some useful hints: >>> >>> - Use JavaGenerator.newJavaWriter() to get a hold of a writer. It takes >>> care of handling imports for you and has some convenience API. Also, it >>> only writes the class if there has been a modification to the previous code >>> generation, allowing for incremental compilation >>> - Use the Database.getConnection() method to get a hold of a JDBC >>> connection. You can use it to query your tables for enum values and >>> descriptions and generate code from that. >>> >>> Then, you will probably need to switch to programmatic code generator >>> configuration in order to dynamically create ForcedType configurations to >>> replace the references to those enum tables by the actual enum types: >>> >>> - >>> https://www.jooq.org/doc/latest/manual/code-generation/codegen-programmatic >>> - >>> https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/ >>> >>> I hope this helps, >>> Lukas >>> >>> On Wed, Sep 5, 2018 at 11:47 PM <[email protected]> wrote: >>> >>>> Hi Lukas, >>>> >>>> Thanks a lot. It has totally sense. I've created the separated project, >>>> added it as a dependency and I could trigger my custom generator (actually >>>> I'm debugging it to learn more), so first knowledge gap closed. >>>> >>>> Now I fall in the real problem that is how to generate the enums using >>>> a specific schema. I'm aware that JOOQ 2.x had this support but was removed >>>> since it was very complex, but my use case is pretty specific and look much >>>> more simpler. >>>> >>>> Can you provide a some details about how to do it? >>>> >>>> Thanks! >>>> Federico >>>> >>>> >>>> On Wednesday, September 5, 2018 at 1:04:03 PM UTC-6, Lukas Eder wrote: >>>>> >>>>> Hi Federico >>>>> >>>>> This is a common issue when creating some custom implementation of a >>>>> code generator extension and expecting the jOOQ GenerationTool to pick it >>>>> up from the classpath. It has to be ... on the classpath. So, this is more >>>>> of a Maven question than a jOOQ related one. For your custom EnumGenerator >>>>> to end up on the GenerationTool's classpath (or rather, the generator >>>>> plugin's classpath), you have to add it as a dependency. This is similar >>>>> to >>>>> when you want to use the JPADatabase and have it pick up JPA annotated >>>>> dependencies from the classpath: >>>>> https://www.jooq.org/doc/latest/manual/code-generation/codegen-jpa >>>>> >>>>> Essentially, just: >>>>> >>>>> 1. Create a separate Maven project containing your EnumGenerator >>>>> 2. Add that project as a dependency to either your "main" project that >>>>> runs the code generator, or to the Maven plugin configuration for the code >>>>> generator >>>>> >>>>> Note: You cannot place the EnumGenerator in the same project that runs >>>>> the code generator plugin, because the code generation phase is >>>>> "generate-sources", which happens before the "compile" phase in Maven. So >>>>> your EnumGenerator is simply not yet compiled and installed, when you >>>>> expect the code generator to consume it. >>>>> >>>>> Hope this helps, >>>>> Lukas >>>>> >>>>> On Wed, Sep 5, 2018 at 7:49 PM <[email protected]> wrote: >>>>> >>>>>> Hi guys, >>>>>> >>>>>> I'm very stuck trying to create a custom generator. Have been >>>>>> investigating a lot regarding this and found this post on SO that is a >>>>>> similar problem to mine: >>>>>> >>>>>> https://stackoverflow.com/questions/46429671/generate-enum-class-from-table-with-jooq >>>>>> >>>>>> This post answer by Lukas, give a good idea of what I should do, >>>>>> however I'd need better details of implementation since I have no clue >>>>>> how >>>>>> to continue. I've created this SO question describing what I need in >>>>>> details >>>>>> https://stackoverflow.com/questions/52171377/how-build-a-jooq-custom-generator. >>>>>> Basically, I have a postgres schema named "enums" where all the tables >>>>>> are >>>>>> like TYPES("name", "description"), and I have to create all groovy (or >>>>>> java) enums like below: >>>>>> >>>>>> enum Types { >>>>>> OPEN("open status"), CLOSE("close status"); >>>>>> >>>>>> private final String id; >>>>>> Types(String id) { this.id = id; } >>>>>> public String getValue() { return id; }} >>>>>> >>>>>> >>>>>> According the post answer I have to create a class extending from >>>>>> JavaGenerator, however I was even unable to trigger my custom generator >>>>>> from the maven plugin. So, by using `*mvn -e jooq-codegen:generate*` >>>>>> I found this error: >>>>>> Caused by: java.lang.ClassNotFoundException: >>>>>> com.ctgengine.customer.jooq.EnumGenerator >>>>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >>>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:424) >>>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:357) >>>>>> at >>>>>> org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:819) >>>>>> >>>>>> In the maven plugin I have this snippet: >>>>>> >>>>>> <generator> >>>>>> <!--<name>org.jooq.codegen.JavaGenerator</name>--> >>>>>> <name>com.ctgengine.customer.jooq.EnumGenerator</name> >>>>>> ... >>>>>> >>>>>> >>>>>> And in my class I have: >>>>>> >>>>>> class EnumGenerator extends JavaGenerator { >>>>>> @Override >>>>>> void generateTables(SchemaDefinition schema) { >>>>>> .... >>>>>> >>>>>> >>>>>> Anyway, if I uncomment the JavaGenerator everything works fine. >>>>>> >>>>>> So, I have two big gaps of knowledge where I need your help: >>>>>> - Why my code isn't being picked by the maven plugin? >>>>>> - Once I could link the plugin to my code, how can I do to generate >>>>>> groovy (or java) enums? >>>>>> >>>>>> Thanks a lot in advance. >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "jOOQ User Group" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "jOOQ User Group" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "jOOQ User Group" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/jooq-user/5lfiz8yFDh0/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "jOOQ User Group" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > -- > You received this message because you are subscribed to a topic in the > Google Groups "jOOQ User Group" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/jooq-user/5lfiz8yFDh0/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
