osalvador / tePLSQL

PL/SQL Template engine
http://osalvador.github.io/tePLSQL/
MIT License
65 stars 18 forks source link

jinja style template inheritance #36

Closed s-oravec closed 4 years ago

s-oravec commented 4 years ago

Implement jinja style template inheritance

s-oravec commented 4 years ago

@osalvador @MikeKutz ping ;)

MikeKutz commented 4 years ago

Not a bad idea. I could actually use this in the templates I build now.

My work-around

On a related note, I've looked into referencing other templates via relative path.

THAT feature would require a massive rewrite such that the engine core is within a UDT. Other UDTs may be needed as well. (eg Stack)

ps - if you desire, I can post those "helper template" generating templates.

dmitrofanov commented 4 years ago

Hi @MaikMichel,

Thanks for your reply. Could you please post some examples of these helper templates? Many thanks!

MikeKutz commented 4 years ago

@dmitrofanov - did you mean to tag Maik or me?

I'm actually preparing a branch (in my fork) that contains these helper templates.

For a function/procedure, the TE_TEMPLATES.NAME of the helper templates are

The "?" gets replaced with the implementation's name (eg com.teplsql.my_tapi.functions.do_something)

I have have "Helper Templates" for Packages, SQL statements, Error Codes, TYPES, and "make the template".

The Packages set of Helper Templates uses the Template Globing feature (eg <%@ include( com.teplsql.my_tapi.functions.*.specification ) %>. So, by copying over a new set of Procedure Helper Template to "com.teplsql.my_tapi..functions.name.xxxx", you automatically get a new Procedure in your next generated Package.

I'll post back up when I have something useful.

MikeKutz commented 4 years ago

As I work to convert my helper templates into tePLSQL format, it looks like I might be able to implement something like jinja.

Right now, you'll have to

  1. generate the template(s) from skeleton helper templates ( done )
  2. modify the generated template(s) (todo)
  3. render the template(s) through the tePLSQL package ( done )

The "instructions" would need to use a hierarchical style file format (eg JSON or XML) in order to describe the process. This is because a database object (rendered by a single helper template) can have multiple sub-objects (rendered by other helper templates).

The exciting thing: I believe that the JSON/XML file could be incorporated (as a template) into an oddgen generator package thus making the sharing of your template that much easier (only the Package containing the JSON is needed).

Let me know your thoughts on this.

MK

example JSON:

{ "type_name":"build", "object_owner":"stuff.my_collection_of_templates", "object_name":"SimpleTAPI",  
    "subObjects":[ { "type_name":"packages", "object_name":"TAPI_package",
                "modify":{ "name":"${table_name}_API",
                           "documentation":"/** simple TAPI for ${schema}.${table_name} */" },
                "subObjects":[ { "type_name":"exceptions", "object_name":"not_yet_implemented",
                    "modify":{"number":"-20013"}
                  }, { "type_name":"functions", "object_name":"ins",
                     "modify":{ "spec":"procedure <%@ include( ##THIS##.name ) %>( rcd in ${schema}.${table}%rowtype )",
                                 "bdy":"insert into ${schema}.${table}
                          values rcd;",
                                 "documentation":"/* produce a new entry */" }
                }, { "type_name":"functions", "object_name":"upd",
                    "modify":{ "spec":"procedure <%@ include( ##THIS##.name ) %>( rcd in ${schema}.${table}%rowtype )",
                               "bdy":"<%@ include( ##PARENT##.exceptions.not_yet_implemented.raise_error %>;\\n",
                               "documentation":"/* update an existing entry */" }
                }, { "type_name":"functions", "object_name":"del",
                    "modify":{ "spec":"procedure <%@ include( ##THIS##.name ) %>( rcd in ${schema}.${table}%rowtype )",
                               "bdy":"delete from ${schema}.${table_name} a
                        where 1=1
                        <% for curr in ""Columns""('${schema}','${table_name}', 'PK') loop %> -- this cursor is defined in the BUILD skeleton
                            and a.<%= curr.column_name %> = rcd.<%= curr.column_name %>
                        <% end loop; %>;\\n" ,
                               "documentation":"/* remove an entry */" }
                }
            ]
        }
    ]
}
MikeKutz commented 4 years ago

Proof of Concept code works but uses an XML file format to describe the build (instead of JSON)

Right now, the build() procedure is a completely separate package.

Let me know if I should keep it that way or combine it into TEPLSQL package.

MikeKutz commented 4 years ago

build() procedure is now in TEPLSQL and works

I just need to figure out the best way on how to solve #43 (and implement that).

Then add some examples of builds (and add/update the documentation), then this can be closed.

MikeKutz commented 4 years ago

@s-oravec I believe all of the code has been developed and pushed into the jinja branch.

note: The <%@ extends %> tags must have a closing <%@ enextends %> tag.

The procedure (found in demo/TEST_BUILD_TAPI.sql) has an example build template. (I still need to automate the build process.)

Let me know what you think.

MK