Pular para o conteúdo

Configurando Grails para utilizar SQLite3

Postado em 3 minutos de leitura

O Grails utiliza o banco de dados HSQLDB por padrão. O que eu quero é utilizar o SQLite3. O primeiro passo é adicionar o JAR sqlite-jdbc como dependência do projeto. Basta editar o arquivo grails-app/conf/BuildConfig.groovy conforme abaixo:

grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.dependency.resolution = {
    inherits("global")
    log "warn"
    repositories {
        grailsPlugins()
        grailsHome()
        grailsCentral()
        mavenCentral()
    }
    dependencies {
        runtime group:'org.xerial', name:'sqlite-jdbc', version:'3.6.16'
    }
}

Depois, execute o comando grails install-dependency:

grails install-dependency

Então crie o arquivo src/java/dialect/SQLiteDialect.java:

package dialect;
 
import java.sql.Types;
 
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.Hibernate;
 
public class SQLiteDialect extends Dialect {
    public SQLiteDialect() {
        super();
        registerColumnType(Types.BIT, "integer");
        registerColumnType(Types.TINYINT, "tinyint");
        registerColumnType(Types.SMALLINT, "smallint");
        registerColumnType(Types.INTEGER, "integer");
        registerColumnType(Types.BIGINT, "bigint");
        registerColumnType(Types.FLOAT, "float");
        registerColumnType(Types.REAL, "real");
        registerColumnType(Types.DOUBLE, "double");
        registerColumnType(Types.NUMERIC, "numeric");
        registerColumnType(Types.DECIMAL, "decimal");
        registerColumnType(Types.CHAR, "char");
        registerColumnType(Types.VARCHAR, "varchar");
        registerColumnType(Types.LONGVARCHAR, "longvarchar");
        registerColumnType(Types.DATE, "date");
        registerColumnType(Types.TIME, "time");
        registerColumnType(Types.TIMESTAMP, "timestamp");
        registerColumnType(Types.BINARY, "blob");
        registerColumnType(Types.VARBINARY, "blob");
        registerColumnType(Types.LONGVARBINARY, "blob");
        // registerColumnType(Types.NULL, "null");
        registerColumnType(Types.BLOB, "blob");
        registerColumnType(Types.CLOB, "clob");
        registerColumnType(Types.BOOLEAN, "integer");
 
        registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "",
                "||", ""));
        registerFunction("mod", new SQLFunctionTemplate(Hibernate.INTEGER,
                "?1 % ?2"));
        registerFunction("substr", new StandardSQLFunction("substr",
                Hibernate.STRING));
        registerFunction("substring", new StandardSQLFunction("substr",
                Hibernate.STRING));
    }
 
    public boolean supportsIdentityColumns() {
        return true;
    }
 
    /*
     public boolean supportsInsertSelectIdentity() {
     return true; // As specify in NHibernate dialect
     }
     */
 
    public boolean hasDataTypeInIdentityColumn() {
        return false; // As specify in NHibernate dialect
    }
 
    /*
     public String appendIdentitySelectToInsert(String insertString) {
     return new StringBuffer(insertString.length()+30). // As specify in NHibernate dialect
     append(insertString).
     append("; ").append(getIdentitySelectString()).
     toString();
     }
     */
 
    public String getIdentityColumnString() {
        // return "integer primary key autoincrement";
        return "integer";
    }
 
    public String getIdentitySelectString() {
        return "select last_insert_rowid()";
    }
 
    public boolean supportsLimit() {
        return true;
    }
 
    public String getLimitString(String query, boolean hasOffset) {
        return new StringBuffer(query.length() + 20).append(query).append(
                hasOffset ? " limit ? offset ?" : " limit ?").toString();
    }
 
    public boolean supportsTemporaryTables() {
        return true;
    }
 
    public String getCreateTemporaryTableString() {
        return "create temporary table if not exists";
    }
 
    public boolean dropTemporaryTableAfterUse() {
        return false;
    }
 
    public boolean supportsCurrentTimestampSelection() {
        return true;
    }
 
    public boolean isCurrentTimestampSelectStringCallable() {
        return false;
    }
 
    public String getCurrentTimestampSelectString() {
        return "select current_timestamp";
    }
 
    public boolean supportsUnionAll() {
        return true;
    }
 
    public boolean hasAlterTable() {
        return false; // As specify in NHibernate dialect
    }
 
    public boolean dropConstraints() {
        return false;
    }
 
    public String getAddColumnString() {
        return "add column";
    }
 
    public String getForUpdateString() {
        return "";
    }
 
    public boolean supportsOuterJoinForUpdate() {
        return false;
    }
 
    public String getDropForeignKeyString() {
        throw new UnsupportedOperationException(
                "No drop foreign key syntax supported by SQLiteDialect");
    }
 
    public String getAddForeignKeyConstraintString(String constraintName,
            String[] foreignKey, String referencedTable, String[] primaryKey,
            boolean referencesPrimaryKey) {
        throw new UnsupportedOperationException(
                "No add foreign key syntax supported by SQLiteDialect");
    }
 
    public String getAddPrimaryKeyConstraintString(String constraintName) {
        throw new UnsupportedOperationException(
                "No add primary key syntax supported by SQLiteDialect");
    }
 
    public boolean supportsIfExistsBeforeTableName() {
        return true;
    }
 
    public boolean supportsCascadeDelete() {
        return false;
    }
}

E por último, configurar a conexão com o banco de dados no arquivo grails-app/conf/DataSource.groovy:

development {
    dataSource {
        dbCreate = "create-drop" // one of 'create', 'create-drop','update'
        url = "jdbc:sqlite:/tmp/meubanco.db"
        logSql = "true"
        dialect = "dialect.SQLiteDialect"
        driverClassName="org.sqlite.JDBC"
    }
}

Ao executar o comando grails run-app será criado o banco de dados /tmp/meubanco.db.