^ Files of XML Meta-Program
A-folder-in-the-project-tree
  |--- go.dal            root-file: an empty file named as 'php.dal', 'java.dal', 'cpp.dal', 'python.dal', or 'go.dal' (ensure lower case)
  |--- sdm.xml           declarations of DTO/model and/or DAO classes
  |--- settings.xml      common settings
  |--- sdm.xsd           ------ XSD-files for XML code completion and parsing
  |--- settings.xsd      ------
  |--- dao.xsd           ------
  |--- ProjectsDao.xml   external XML files as an option to declare DAO classes
Initial Steps

  1. Create/Open an SDM folder (any name)
  2. Create/Open (double-click) a root-file to enter the Plug-in GUI, switch to "Admin"
  3. Create XSD files, "sdm.xml", and "settings.xml".
  4. Click "settings.xml" to start editing. Read and follow the notes in XML comments. Save the changes.
  5. The buttons marked as [x] may be good starting points.

Real examples of "settings.xml" are available in Demo Projects.

This is a typical one (Android): https://github.com/panedrone/sdm_thesaurus_android/blob/master/sdm/settings.xml

See also a Quick Demo Video.

^ settings.xml -> examples of JDBC settings
JDBC Driver XML tag in 'settings.xml'
MySQL <jdbc jar="lib/mysql-connector-java-8.0.13.jar" class="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost/sakila" user="root" pwd="root"/>
Oracle <jdbc jar="lib/ojdbc8.jar" class="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl" user="ORDERS" pwd="sa"/>
PostgreSQL <jdbc jar="postgresql-42.2.9.jar" class="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/orders" user="postgres" pwd="sa"/>
SQL Server <jdbc jar="mssql-jdbc-8.2.2.jre11.jar" class="com.microsoft.sqlserver.jdbc.SQLServerDriver" url="jdbc:sqlserver://localhost\SQLEXPRESS;databaseName=AdventureWorks2014" user="sa" pwd="root"/>
xerial / sqlite-jdbc <jdbc jar="sqlite-jdbc-3.40.0.0.jar" class="org.sqlite.JDBC" url="jdbc:sqlite:$PROJECT_DIR$/northwindEF.sqlite" user="" pwd=""/>
H2 <jdbc jar="h2-1.4.190.jar" class="org.h2.Driver" url="jdbc:h2:$PROJECT_DIR$/h2_orders" user="" pwd="" />
^ settings.xml -> type-map

Here you specify how the types detected by code generator are rendered in the target code.

<type-map default="">
    <type detected="java.lang.Integer" target="int64">
    <type detected="java.lang.Double" target="float64">
    <type detected="java.lang.Float" target="float64">
    <type detected="java.lang.String" target="string">
    <type detected="byte[]" target="[]byte"/>
    <type detected="java.lang.Object" target="interface{}"/>
</type-map>

Algorithm of processing is the following:

  1. if detected type is found among 'detected', then related 'target' is rendered
  2. if not, then 'default' is rendered
  3. if 'default' is empty, detected type is rendered as-is.

If you want to create "type-map" from zero, read this: misc.html#type-map.

if you need more strong typing in generated DAO classes, read this: misc.html#strong-typing.

There may be some nuances depending on database/driver.

Example 1. MySQL JDBC driver detects all field types correctly. At the same time, MySQL divers for Go fetch all values as []uint8:

Example 2. Oracle JDBC driver detects all numerics as "java.math.BigDecimal". At the same time, Go + "github.com/godror/godror" fetches all numerics as strings:

Example 3. For Java + Android + SQLite, you may need this:

<type-map default="">
    <!-- On Dev. PC, it is Integer, but in Android run-time it is Long -->
    <type detected="java.lang.Integer" target="java.lang.Long"/>
</type-map>

Example 4. JDBC driver for SQLite3 detects date/time as "java.lang.String" or "java.lang.Object", but it happens that Go + "github.com/mattn/go-sqlite3" fetches date/time as "time:time.Time".
In such cases, 'type-map' may be not working, and you need explicit declarations:

<dto-class name="Orders" ref="get_orders.sql">
    <field type="time:time.Time" column="o_date"/>
</dto-class>
^ settings.xml -> macros

To generate complex fields like in example below

class Task(Base):
    __tablename__ = 'tasks'

    t_id = Column('t_id', Integer, primary_key=True, autoincrement=True)
    g_id = Column('g_id', Integer, ForeignKey('groups.g_id'))
    t_priority = Column('t_priority', Integer)
    t_date = Column('t_date', String(65535))
    t_subject = Column('t_subject', String(65535))
    t_comments = Column('t_comments', String(65535))

you will need to extend the section "settings.xml" => <macros> and use related references in "settings.xml" => <type-map><type ... target="...:

<type-map default="">
    <type detected="sa-java.lang.Integer" target="${sa-type}|0:Integer"/>
    <type detected="sa-java.lang.Float" target="${sa-type}|0:Float"/>
    <type detected="sa-java.lang.String" target="${sa-type}|0:String"/>
    <type detected="sa-byte[]" target="${sa-type}|0:LargeBinary"/>
    <type detected="sa-java.lang.Object" target="${sa-type-unknown}"/>
type-map>
<macros>
    <macro name="${sa-type-unknown}" value="${sa-column-base}|type:"/>

    <macro name="${sa-type}" value="${sa-column-base}|type:, ${0}"/>

    <macro name="${sa-column-base}"/>
            <vm/>
                <![CDATA[= Column('${column}'${type}#if($fi.ColumnSize>0)($fi.ColumnSize)#end#if($fi.FK), ForeignKey('$fi.FK')#end
#if($fi.PK), primary_key=True#end
#if($fi.AI), autoincrement=True#end
#if(!$fi.PK)
#if($fi.Indexed), index=True#end
#if($fi.Unique), unique=True#end
#if($fi.Nullable), nullable=True#end
#end)${comment}]]/>
            </vm/>
    </macro/>
macros>

Examples of the field-related macros are available in plug-in GUI => tab "Admin" => [X] and in Demo-Projects: https://github.com/panedrone/sqldalmaker

To customize class-based macros, use this:

  • refs to entries of section <macros>:

    <dto scope="" inheritance="" field-names-mode="0" macro="${dto}"/>
    <dao scope="" field-assign-mode="0" macro="${dao}"/>
  • refs to external files:

    <dto scope="" inheritance="" field-names-mode="0" macro="sdm/python.models.vm"/>
    <dao scope="" field-assign-mode="0" macro="sdm/python.dao.vm"/>
^ Areas of Responsibility
  • Use a proxy to wrap low-level logic of DB API (PDO, JDBC, QtSql, Python DB-API, Gorm, etc.).
  • Publish meaningful functions of proxy with a simple interface "DataStore".
  • Share a single instance of proxy between all the instances of DAO classes (not an inheritance).
  • No low-level DB API in generated code, only "DataStore".

Below is an example demonstrating how to organize it in Golang:

Interface DataStore
type DataStore interface {
	Db() *sqlx.DB

	Open() error
	Close() error

	Begin(ctx context.Context) (txCtx context.Context, err error)
	Commit(txCtx *context.Context) error
	Rollback(txCtx *context.Context) error

	// the methods called by generated code:

	Insert(ctx context.Context, sqlString string, aiNames string, args ...interface{}) (id interface{}, err error)
	Exec(ctx context.Context, sqlString string, args ...interface{}) (rowsAffected int64, err error)

	Query(ctx context.Context, sqlString string, destPtr interface{}, args ...interface{}) error
	QueryAll(ctx context.Context, sqlString string, destSlicePtr interface{}, args ...interface{}) error
	QueryRow(ctx context.Context, sqlString string, args ...interface{}) (row map[string]interface{}, err error)
	QueryAllRows(ctx context.Context, sqlString string, onRow func(map[string]interface{}), args ...interface{}) error

	Select(ctx context.Context, sqlString string, dest interface{}, args ...interface{}) error
}
An implementation (proxy) https://github.com/panedrone/sdm_todolist_go_react_vue_npm_sqlite3/blob/master/sqlx/dbal/data_store_sqlx.go
Usage in a generated DAO class https://github.com/panedrone/sdm_todolist_go_react_vue_npm_sqlite3/blob/master/sqlx/dbal/projects_dao.go

For more examples, refer Demo-Projects and the plugin GUI, tab 'Admin'.

Lower level DB accessing API Comments
PHP MySQL, Oracle, PostgreSQL, SQL Server, SQLite3
Java Available through JDBC:
MySQL, Oracle, PostgreSQL, SQL Server, SQLite3, H2, HSQLDB, Derby, IBM DB2, IBM Informix, Firebird, etc.
C++ Databases supported by Qt: http://doc.qt.io/qt-5/sql-driver.html
Python -
Go Tested with MySQL, Oracle, PostgreSQL, SQL Server, and SQLite3.

^ Top