Search in sources :

Example 1 with DBVendor

use of org.jaxdb.vendor.DBVendor in project jaxdb by jaxdb.

the class InsertTest method testInsertBatch.

@Test
public void testInsertBatch(@Schema(types.class) final Transaction transaction) throws IOException, SQLException {
    final DBVendor vendor = transaction.getVendor();
    final boolean isOracle = vendor == DBVendor.ORACLE;
    final Batch batch = new Batch();
    batch.addStatement(INSERT(t1), (e, c) -> assertEquals(isOracle ? 0 : 1, c));
    batch.addStatement(INSERT(t2), (e, c) -> assertEquals(isOracle ? 0 : 1, c));
    batch.addStatement(INSERT(t3.id, t3.bigintType, t3.charType, t3.doubleType, t3.tinyintType, t3.timeType), (e, c) -> assertEquals(isOracle ? 0 : 1, c));
    assertEquals(isOracle ? 0 : 3, batch.execute(transaction));
    if (isOracle || vendor == DBVendor.DERBY || vendor == DBVendor.SQLITE)
        return;
    final int id = getMaxId(transaction, t1);
    assertEquals(id - 2, t1.id.getAsInt());
    assertEquals(id - 1, t2.id.getAsInt());
    assertEquals(id - 0, t3.id.getAsInt());
}
Also used : Batch(org.jaxdb.jsql.Batch) DBVendor(org.jaxdb.vendor.DBVendor) Test(org.junit.Test)

Example 2 with DBVendor

use of org.jaxdb.vendor.DBVendor in project jaxdb by jaxdb.

the class Connector method addNotificationListener0.

@SuppressWarnings({ "resource", "unchecked" })
private <T extends data.Table<?>> boolean addNotificationListener0(final INSERT insert, final UP up, final DELETE delete, final Notification.Listener<T> notificationListener, final Queue<Notification<T>> queue, final T... tables) throws IOException, SQLException {
    assertNotNull(notificationListener);
    assertNotEmpty(tables);
    if (notifier == null) {
        final Connection connection = connectionFactory.getConnection();
        final DBVendor vendor = DBVendor.valueOf(connection.getMetaData());
        if (vendor == DBVendor.POSTGRE_SQL) {
            notifier = new PostgreSQLNotifier(connection, this);
        } else {
            connection.close();
            throw new UnsupportedOperationException("Unsupported DBVendor: " + vendor);
        }
    }
    return notifier.addNotificationListener(insert, up, delete, notificationListener, queue, tables);
}
Also used : Connection(java.sql.Connection) DBVendor(org.jaxdb.vendor.DBVendor)

Example 3 with DBVendor

use of org.jaxdb.vendor.DBVendor in project jaxdb by jaxdb.

the class Generator method main.

public static void main(final String[] args) throws GeneratorExecutionException, IOException, SAXException, TransformerException {
    if (args.length != 5)
        trapPrintUsage();
    DBVendor vendor = null;
    File destDir = null;
    URL schemaUrl = null;
    String sqlFileName = null;
    for (int i = 0; i < args.length; ++i) {
        if ("-v".equals(args[i]))
            vendor = DBVendor.valueOf(args[++i]);
        else if ("-d".equals(args[i]))
            destDir = new File(args[++i]).getAbsoluteFile();
        else {
            final File schemaFile = new File(args[i]);
            sqlFileName = schemaFile.getName().substring(0, schemaFile.getName().lastIndexOf('.') + 1) + "sql";
            schemaUrl = schemaFile.getAbsoluteFile().toURI().toURL();
        }
    }
    if (vendor == null || destDir == null || schemaUrl == null) {
        trapPrintUsage();
    } else {
        final StatementBatch statementBatch = createDDL(new DDLx(schemaUrl), vendor);
        destDir.mkdirs();
        statementBatch.writeOutput(new File(destDir, sqlFileName));
    }
}
Also used : DBVendor(org.jaxdb.vendor.DBVendor) File(java.io.File) URL(java.net.URL)

Example 4 with DBVendor

use of org.jaxdb.vendor.DBVendor in project jaxdb by jaxdb.

the class Batch method execute.

@SuppressWarnings({ "null", "resource", "unchecked" })
private int execute(final Transaction transaction, final String dataSourceId) throws IOException, SQLException {
    if (statements == null)
        return 0;
    AtomicReference<int[]> countRef = new AtomicReference<>();
    try {
        final int noStatements = statements.size();
        final Consumer<Transaction.Event>[] eventListeners = new Consumer[noStatements];
        final InsertImpl<?>[] insertsWithGeneratedKeys = new InsertImpl<?>[noStatements];
        final Compilation[] compilations = new Compilation[noStatements];
        final Connection connection;
        final Connector connector;
        String last = null;
        Statement statement = null;
        SQLException suppressed = null;
        boolean isPrepared;
        int total = 0;
        int index = 0;
        final Command<?> command0 = (Command<?>) statements.get(0);
        final Class<? extends Schema> schema = command0.schema();
        if (transaction != null) {
            connector = transaction.getConnector();
            connection = transaction.getConnection();
            isPrepared = transaction.isPrepared();
        } else {
            connector = Database.getConnector(command0.schema(), dataSourceId);
            connection = connector.getConnection();
            connection.setAutoCommit(true);
            isPrepared = connector.isPrepared();
        }
        try {
            int listenerIndex = 0;
            for (int statementIndex = 0, eventIndex = 0; statementIndex < noStatements; ++statementIndex) {
                final Command<?> command = (Command<?>) statements.get(statementIndex);
                if (schema != command.schema())
                    throw new IllegalArgumentException("Cannot execute batch across different schemas: " + schema.getSimpleName() + " and " + command.schema().getSimpleName());
                final DBVendor vendor = DBVendor.valueOf(connection.getMetaData());
                final Compiler compiler = Compiler.getCompiler(vendor);
                if (isPrepared && !compiler.supportsPreparedBatch()) {
                    if (logger.isWarnEnabled())
                        logger.warn(vendor + " does not support prepared statement batch execution");
                    isPrepared = false;
                }
                final boolean returnGeneratedKeys;
                if (command instanceof InsertImpl && ((InsertImpl<?>) command).autos.length > 0) {
                    if (!compiler.supportsReturnGeneratedKeysBatch()) {
                        if (logger.isWarnEnabled())
                            logger.warn(vendor + " does not support return of generated keys during batch execution");
                        returnGeneratedKeys = false;
                    } else if (returnGeneratedKeys = isPrepared) {
                        insertsWithGeneratedKeys[statementIndex] = (InsertImpl<?>) command;
                    } else if (logger.isWarnEnabled()) {
                        logger.warn("Generated keys can only be provided with prepared statement batch execution");
                    }
                } else {
                    returnGeneratedKeys = false;
                }
                final Compilation compilation = compilations[statementIndex] = new Compilation(command, vendor, isPrepared);
                command.compile(compilation, false);
                final String sql = compilation.toString();
                if (isPrepared) {
                    if (!(statement instanceof PreparedStatement) || !sql.equals(last)) {
                        if (statement != null) {
                            try {
                                final int[] counts = statement.executeBatch();
                                total = aggregate(counts, statement, insertsWithGeneratedKeys, index, total);
                                index += counts.length;
                                countRef.set(counts);
                                countRef = new AtomicReference<>();
                                notifyListenerEvent(Transaction.Event.EXECUTE, eventListeners, listenerIndex, statementIndex);
                                afterExecute(compilations, listenerIndex, statementIndex);
                                addListenerCommit(transaction, eventListeners, listenerIndex, statementIndex);
                                listenerIndex = statementIndex;
                                eventIndex = 0;
                            } finally {
                                suppressed = Throwables.addSuppressed(suppressed, AuditStatement.close(statement));
                            }
                        }
                        statement = returnGeneratedKeys ? connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : connection.prepareStatement(sql);
                        last = sql;
                    }
                    final List<data.Column<?>> parameters = compilation.getParameters();
                    if (parameters != null)
                        for (int p = 0, len = parameters.size(); p < len; ) parameters.get(p).get((PreparedStatement) statement, ++p);
                    ((PreparedStatement) statement).addBatch();
                } else {
                    if (statement == null) {
                        statement = connection.createStatement();
                    } else if (statement instanceof PreparedStatement) {
                        try {
                            final int[] counts = statement.executeBatch();
                            total = aggregate(counts, statement, insertsWithGeneratedKeys, index, total);
                            index += counts.length;
                            countRef.set(counts);
                            countRef = new AtomicReference<>();
                            notifyListenerEvent(Transaction.Event.EXECUTE, eventListeners, listenerIndex, statementIndex);
                            afterExecute(compilations, listenerIndex, statementIndex);
                            addListenerCommit(transaction, eventListeners, listenerIndex, statementIndex);
                            listenerIndex = statementIndex;
                            eventIndex = 0;
                        } finally {
                            suppressed = Throwables.addSuppressed(suppressed, AuditStatement.close(statement));
                        }
                        statement = connection.createStatement();
                    }
                    statement.addBatch(sql);
                }
                addEventListener(connector, connection, command, eventListeners, countRef, statementIndex, eventIndex++);
            }
            final int[] counts = statement.executeBatch();
            total = aggregate(counts, statement, insertsWithGeneratedKeys, index, total);
            index += counts.length;
            countRef.set(counts);
            notifyListenerEvent(Transaction.Event.EXECUTE, eventListeners, listenerIndex, noStatements);
            afterExecute(compilations, listenerIndex, noStatements);
            addListenerCommit(transaction, eventListeners, listenerIndex, noStatements);
            return total;
        } finally {
            SQLException e = Throwables.addSuppressed(statement == null ? null : AuditStatement.close(statement), suppressed);
            if (transaction == null && connection != null)
                e = Throwables.addSuppressed(e, AuditConnection.close(connection));
            if (e != null)
                throw e;
        }
    } catch (final SQLException e) {
        throw SQLExceptions.toStrongType(e);
    }
}
Also used : SQLException(java.sql.SQLException) DBVendor(org.jaxdb.vendor.DBVendor) ObjIntConsumer(java.util.function.ObjIntConsumer) Consumer(java.util.function.Consumer) PreparedStatement(java.sql.PreparedStatement) AuditStatement(org.libj.sql.AuditStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) AuditConnection(org.libj.sql.AuditConnection) AtomicReference(java.util.concurrent.atomic.AtomicReference) PreparedStatement(java.sql.PreparedStatement)

Example 5 with DBVendor

use of org.jaxdb.vendor.DBVendor in project jaxdb by jaxdb.

the class Decompiler method createDDL.

public static Schema createDDL(final Connection connection) throws SQLException {
    final DBVendor vendor = DBVendor.valueOf(connection.getMetaData());
    final Decompiler decompiler = Decompiler.getDecompiler(vendor);
    final DatabaseMetaData metaData = connection.getMetaData();
    try (final ResultSet tableRows = metaData.getTables(null, null, null, new String[] { "TABLE" })) {
        final Schema schema = new Schema();
        final Map<String, List<$CheckReference>> tableNameToChecks = decompiler.getCheckConstraints(connection);
        final Map<String, List<$Table.Constraints.Unique>> tableNameToUniques = decompiler.getUniqueConstraints(connection);
        final Map<String, $Table.Indexes> tableNameToIndexes = decompiler.getIndexes(connection);
        final Map<String, Map<String, $ForeignKeyUnary>> tableNameToForeignKeys = decompiler.getForeignKeys(connection);
        final Map<String, $Column> columnNameToColumn = new HashMap<>();
        final Map<Integer, $Column> columnNumberToColumn = new TreeMap<>();
        final Map<String, TreeMap<Short, String>> indexNameToIndex = new HashMap<>();
        final Map<String, String> indexNameToType = new HashMap<>();
        final Map<String, Boolean> indexNameToUnique = new HashMap<>();
        while (tableRows.next()) {
            final String tableName = tableRows.getString(3);
            final $Table table = new Schema.Table();
            table.setName$(new $Named.Name$(tableName.toLowerCase()));
            schema.addTable(table);
            try (final ResultSet columnRows = metaData.getColumns(null, null, tableName, null)) {
                while (columnRows.next()) {
                    final String columnName = columnRows.getString("COLUMN_NAME").toLowerCase();
                    final String typeName = columnRows.getString("TYPE_NAME");
                    final int columnSize = columnRows.getInt("COLUMN_SIZE");
                    final String _default = columnRows.getString("COLUMN_DEF");
                    final int index = columnRows.getInt("ORDINAL_POSITION");
                    final String nullable = columnRows.getString("IS_NULLABLE");
                    final String autoIncrement = columnRows.getString("IS_AUTOINCREMENT");
                    final int decimalDigits = columnRows.getInt("DECIMAL_DIGITS");
                    final $Column column = decompiler.makeColumn(columnName.toLowerCase(), typeName, columnSize, decimalDigits, _default, nullable.length() == 0 ? null : "YES".equals(nullable), autoIncrement.length() == 0 ? null : "YES".equals(autoIncrement));
                    columnNameToColumn.put(columnName, column);
                    columnNumberToColumn.put(index, column);
                }
                columnNumberToColumn.values().forEach(table::addColumn);
                try (final ResultSet primaryKeyRows = metaData.getPrimaryKeys(null, null, tableName)) {
                    while (primaryKeyRows.next()) {
                        final String columnName = primaryKeyRows.getString("COLUMN_NAME").toLowerCase();
                        if (table.getConstraints() == null)
                            table.setConstraints(new $Table.Constraints());
                        if (table.getConstraints().getPrimaryKey() == null)
                            table.getConstraints().setPrimaryKey(new $Table.Constraints.PrimaryKey());
                        final $Table.Constraints.PrimaryKey.Column column = new $Table.Constraints.PrimaryKey.Column();
                        column.setName$(new $Table.Constraints.PrimaryKey.Column.Name$(columnName));
                        table.getConstraints().getPrimaryKey().addColumn(column);
                    }
                }
                final List<$Table.Constraints.Unique> uniques = tableNameToUniques == null ? null : tableNameToUniques.get(tableName);
                if (uniques != null && uniques.size() > 0) {
                    if (table.getConstraints() == null)
                        table.setConstraints(new $Table.Constraints());
                    for (final $Table.Constraints.Unique unique : uniques) table.getConstraints().addUnique(unique);
                }
                try (final ResultSet indexRows = metaData.getIndexInfo(null, null, tableName, false, true)) {
                    while (indexRows.next()) {
                        final String columnName = indexRows.getString("COLUMN_NAME").toLowerCase();
                        if (columnName == null)
                            continue;
                        final String indexName = indexRows.getString("INDEX_NAME").toLowerCase();
                        TreeMap<Short, String> indexes = indexNameToIndex.get(indexName);
                        if (indexes == null)
                            indexNameToIndex.put(indexName, indexes = new TreeMap<>());
                        final short ordinalPosition = indexRows.getShort("ORDINAL_POSITION");
                        indexes.put(ordinalPosition, columnName);
                        final String type = getType(indexRows.getShort("TYPE"));
                        final String currentType = indexNameToType.get(indexName);
                        if (currentType == null)
                            indexNameToType.put(indexName, type);
                        else if (!type.equals(currentType))
                            throw new IllegalStateException("Expected " + type + " = " + currentType);
                        final boolean unique = !indexRows.getBoolean("NON_UNIQUE");
                        final Boolean currentUnique = indexNameToUnique.get(indexName);
                        if (currentUnique == null)
                            indexNameToUnique.put(indexName, unique);
                        else if (unique != currentUnique)
                            throw new IllegalStateException("Expected " + unique + " = " + currentType);
                    }
                }
                final $Table.Indexes indexes = tableNameToIndexes == null ? null : tableNameToIndexes.get(tableName);
                if (indexes != null)
                    table.setIndexes(indexes);
                final List<$CheckReference> checks = tableNameToChecks == null ? null : tableNameToChecks.get(tableName);
                if (checks != null)
                    for (final $CheckReference check : checks) addCheck(columnNameToColumn.get(check.getColumn$().text()), check);
                final Map<String, $ForeignKeyUnary> foreignKeys = tableNameToForeignKeys == null ? null : tableNameToForeignKeys.get(tableName);
                if (foreignKeys != null)
                    for (final Map.Entry<String, $ForeignKeyUnary> entry : foreignKeys.entrySet()) columnNameToColumn.get(entry.getKey().toLowerCase()).setForeignKey(entry.getValue());
            }
            columnNameToColumn.clear();
            columnNumberToColumn.clear();
            indexNameToIndex.clear();
            indexNameToType.clear();
        }
        return schema;
    }
}
Also used : HashMap(java.util.HashMap) Schema(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Named(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Named) ResultSet(java.sql.ResultSet) List(java.util.List) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Boolean(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Boolean) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column) DatabaseMetaData(java.sql.DatabaseMetaData) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$ForeignKeyUnary(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$ForeignKeyUnary) DBVendor(org.jaxdb.vendor.DBVendor) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$CheckReference(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$CheckReference) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Column) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$CheckColumn(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$CheckColumn) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Table) TreeMap(java.util.TreeMap) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Tinyint(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Tinyint) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Bigint(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Bigint) org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Smallint(org.jaxdb.www.ddlx_0_5.xLygluGCXAA.$Smallint)

Aggregations

DBVendor (org.jaxdb.vendor.DBVendor)9 File (java.io.File)3 URL (java.net.URL)3 Connection (java.sql.Connection)3 Statement (java.sql.Statement)2 Map (java.util.Map)2 URLClassLoader (java.net.URLClassLoader)1 DatabaseMetaData (java.sql.DatabaseMetaData)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 TreeMap (java.util.TreeMap)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Consumer (java.util.function.Consumer)1 ObjIntConsumer (java.util.function.ObjIntConsumer)1 MojoExecutionException (org.apache.maven.plugin.MojoExecutionException)1 Batch (org.jaxdb.jsql.Batch)1