/** * Add primary key conditions to a query */ @SuppressWarnings("deprecation") static final void addConditions(org.jooq.ConditionProvider query, Record record, Field<?>... keys) { for (Field<?> field : keys) { addCondition(query, record, field); } }
private static final <U> U attach(U value, Configuration configuration) { // [#4372] Attach records if possible / required if (value instanceof Attachable && attachRecords(configuration)) ((Attachable) value).attach(configuration); return value; }
@Override public final void accept(Context<?> ctx) { if (ifExists && !supportsIfExists(ctx)) { Tools.beginTryCatch(ctx, DDLStatementType.DROP_SCHEMA); accept0(ctx); Tools.endTryCatch(ctx, DDLStatementType.DROP_SCHEMA); } else { accept0(ctx); } }
final Field<?>[] originalFields = Tools.fieldArray(getSelect()); final Name[] originalNames = Tools.fieldNames(originalFields); final Name[] alternativeNames = Tools.fieldNames(originalFields.length); final Field<?>[] alternativeFields = Tools.combine( alternativeNames.length == 0 ? new Field[] { DSL.field("*") } : Tools.aliasedFields(originalFields, alternativeNames), final Field<?>[] unaliasedFields = Tools.aliasedFields(Tools.fields(originalFields.length), originalNames);
static <T> Supplier<T> blocking(Supplier<T> supplier, boolean threadLocal) { // [#5377] In ThreadLocal contexts (e.g. when using ThreadLocalTransactionprovider), // no ManagedBlocker is needed as we're guaranteed by API contract to always // remain on the same thread. return threadLocal ? supplier : new Supplier<T>() { volatile T asyncResult; @Override public T get() { try { ForkJoinPool.managedBlock(new ManagedBlocker() { @Override public boolean block() { asyncResult = supplier.get(); return true; } @Override public boolean isReleasable() { return asyncResult != null; } }); } catch (InterruptedException e) { throw new RuntimeException(e); } return asyncResult; } }; }
@Override public <R extends UpdatableRecord<R>> int executeDelete(R record) { DeleteQuery<R> delete = deleteQuery(record.getTable()); Tools.addConditions(delete, record, record.getTable().getPrimaryKey().getFieldsArray()); return delete.execute(); }
begin(ctx); beginExecuteImmediate(ctx); break; begin(ctx); for (String sqlstate : sqlstates) ctx.visit(keyword("declare continue handler for sqlstate")).sql(' ').visit(DSL.inline(sqlstate)).sql(' ').visit(K_BEGIN).sql(' ').visit(K_END).sql(';').formatSeparator(); begin(ctx); break;
Name[] aliases = fieldNames(insertMaps.fields().toArray(EMPTY_FIELD)); select(aliasedFields(map.values().toArray(EMPTY_FIELD), aliases)) .whereNotExists( selectOne()
public TableImpl(Name name, Schema schema, Table<?> child, ForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment) { super(name, schema, comment); this.fields = new Fields<R>(); this.child = child; this.childPath = path; if (aliased != null) { // [#7115] Allow for aliased expressions (e.g. derived tables) to be passed to TableImpl // in order to support "type safe views" Alias<Table<R>> existingAlias = Tools.alias(aliased); if (existingAlias != null) alias = new Alias<Table<R>>(existingAlias.wrapped, this, name, existingAlias.fieldAliases, existingAlias.wrapInParentheses); else alias = new Alias<Table<R>>(aliased, this, name); } else alias = null; this.parameters = parameters; }
/** * Wrap a <code>DROP .. IF EXISTS</code> statement with * <code>BEGIN EXECUTE IMMEDIATE '...' EXCEPTION WHEN ... END;</code>, if * <code>IF EXISTS</code> is not supported. */ static final void beginTryCatch(Context<?> ctx, DDLStatementType type) { beginTryCatch(ctx, type, null, null); }
/** * {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public final <O extends Record> List<ForeignKey<R, O>> getReferencesTo(Table<O> other) { List<ForeignKey<R, O>> result = new ArrayList<ForeignKey<R, O>>(); for (ForeignKey<R, ?> reference : getReferences()) { if (other.equals(reference.getKey().getTable())) { result.add((ForeignKey<R, O>) reference); } // [#1460] [#6304] In case the other table was aliased else { Table<O> aliased = Tools.aliased(other); if (aliased != null && aliased.equals(reference.getKey().getTable())) { result.add((ForeignKey<R, O>) reference); } } } return Collections.unmodifiableList(result); }
private final void alterColumnTypeAndNullabilityInBlock(Context<?> ctx) { begin(ctx); accept1(ctx); ctx.sql(';').formatSeparator(); switch (ctx.family()) { case POSTGRES: { AlterTableAlterStep<?> step = ctx.dsl().alterTable(table).alterColumn(alterColumn); ctx.visit(alterColumnType.nullable() ? step.dropNotNull() : step.setNotNull()); break; } } end(ctx); }
@Override public final CompletionStage<Integer> executeAsync(Executor executor) { return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::execute), executor), () -> executor); }
@Override public <R extends UpdatableRecord<R>> int executeUpdate(R record) { UpdateQuery<R> update = updateQuery(record.getTable()); Tools.addConditions(update, record, record.getTable().getPrimaryKey().getFieldsArray()); update.setRecord(record); return update.execute(); }
private final Table<?> search(Table<?> tree, Table<?> search) { // [#6304] Improved alias discovery Alias<? extends Table<?>> alias = Tools.alias(tree); if (alias != null) { return search(alias.wrapped(), search); } else if (tree instanceof JoinTable) { JoinTable t = (JoinTable) tree; Table<?> r = search(t.lhs, search); if (r == null) r = search(t.rhs, search); return r; } else { return search.equals(tree) ? tree : null; } }
@Override public final void accept(Context<?> ctx) { if (ifNotExists && !supportsIfNotExists(ctx)) { Tools.beginTryCatch(ctx, DDLStatementType.CREATE_SCHEMA); accept0(ctx); Tools.endTryCatch(ctx, DDLStatementType.CREATE_SCHEMA); } else { accept0(ctx); } }
private final void accept0(Context<?> ctx) { boolean c = comment != null && EMULATE_COMMENT_IN_BLOCK.contains(ctx.family()); boolean i = !indexes.isEmpty() && EMULATE_INDEXES_IN_BLOCK.contains(ctx.family()); if (c || i) { begin(ctx); accept1(ctx); ctx.sql(';'); if (c) { ctx.formatSeparator(); ctx.visit(commentOnTable(table).is(comment)); ctx.sql(';'); } if (i) { for (Index index : indexes) { ctx.formatSeparator(); if ("".equals(index.getName())) ctx.visit(createIndex().on(index.getTable(), index.getFields())); else ctx.visit(createIndex(index.getUnqualifiedName()).on(index.getTable(), index.getFields())); ctx.sql(';'); } } end(ctx); return; } accept1(ctx); }
@Override public final CompletionStage<Result<R>> fetchAsync(Executor executor) { return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::fetch), executor), () -> executor); }
/** * Perform an additional SELECT .. FOR UPDATE to check if the underlying * database record has been changed compared to this record. */ private final void checkIfChanged(TableField<R, ?>[] keys) { SelectQuery<R> select = create().selectQuery(getTable()); Tools.addConditions(select, this, keys); // [#1547] MS Access and SQLite doesn't support FOR UPDATE. CUBRID and SQL Server // can emulate it, though! if (!NO_SUPPORT_FOR_UPDATE.contains(create().configuration().dialect().family())) select.setForUpdate(true); R record = select.fetchOne(); if (record == null) throw new DataChangedException("Database record no longer exists"); for (Field<?> field : fields.fields.fields) { Object thisObject = original(field); Object thatObject = record.original(field); if (!StringUtils.equals(thisObject, thatObject)) throw new DataChangedException("Database record has been changed"); } }