@Override public final String getSchemaName(int column) throws SQLException { checkNotClosed(); Field<?> field = result.getField(column - 1); if (field instanceof TableField) { Table<?> table = ((TableField<?, ?>) field).getTable(); if (table != null) { Schema schema = table.getSchema(); if (schema != null) { Configuration configuration = ((AttachableInternal) result).getConfiguration(); Schema mapped = null; if (configuration != null) { mapped = Utils.getMappedSchema(configuration, schema); } if (mapped != null) { return mapped.getName(); } else { return schema.getName(); } } } } // By default, no schema is available return ""; }
/** * Get the returning record in those dialects that do not support fetching arbitrary fields from * JDBC's {@link Statement#getGeneratedKeys()} method. */ @SuppressWarnings("unchecked") private final void selectReturning(Configuration configuration, Object... values) { if (values != null && values.length > 0) { // This shouldn't be null, as relevant dialects should // return empty generated keys ResultSet if (into.getIdentity() != null) { Field<Number> field = (Field<Number>) into.getIdentity().getField(); Number[] ids = new Number[values.length]; for (int i = 0; i < values.length; i++) { ids[i] = field.getDataType().convert(values[i]); } // Only the IDENTITY value was requested. No need for an // additional query if (returning.size() == 1 && new Fields(returning).field(field) != null) { for (Number id : ids) { R typed = Utils.newRecord(into, configuration); ((AbstractRecord) typed).setValue(field, new Value<Number>(id)); getReturnedRecords().add(typed); } } // Other values are requested, too. Run another query else { returned = create(configuration) .select(returning) .from(into) .where(field.in(ids)) .fetchInto(into); } } } }
private String[] getTableNames() { if (databaseDescriptor == null) { return new String[0]; } List<Table<?>> tableList = databaseDescriptor.getSchema().getTables(); List<String> tableNameList = new ArrayList<String>(); for (Table<? extends Record> table : tableList) { String tableName = table.getName(); tableNameList.add(tableName); } Collections.sort(tableNameList, String.CASE_INSENSITIVE_ORDER); return tableNameList.toArray(new String[0]); }
protected final Field<?> getField(Table<?> table, String name) { Field<?> result = table.field(name); if (result == null) { result = table.field(name.toUpperCase()); } if (result == null) { result = table.field(name.toLowerCase()); } return result; }
private String[] getTableColumnNames() { if (databaseDescriptor == null) { return new String[0]; } Set<String> columnNameSet = new HashSet<String>(); for (Table<?> table : databaseDescriptor.getSchema().getTables()) { for (Field<?> field : table.getFields()) { String columnName = field.getName(); columnNameSet.add(columnName); } } String[] columnNames = columnNameSet.toArray(new String[0]); Arrays.sort(columnNames, String.CASE_INSENSITIVE_ORDER); return columnNames; }
public void init() { SqlService sql = Sponge.getServiceManager() .provide(SqlService.class) .orElseThrow(() -> new IllegalStateException("NoSQL?")); String jdbcUrl = Planetesimals.getInstance().getJDBCUrl(); String[] dbParts = jdbcUrl.split(":"); if (dbParts.length < 2 || !dbParts[1].equals("h2")) { throw new IllegalStateException("Not H2. Dunno what to do."); } try { this.data = sql.getDataSource(jdbcUrl); } catch (SQLException e) { throw new IllegalStateException("Couldn't load DB", e); } this.db = using(this.data, SQLDialect.H2); if (getDB() .meta() .getTables() .stream() .noneMatch(t -> t.getName().equalsIgnoreCase(PLANETS_TABLE.getName()))) { getDB() .createTable(PLANETS_TABLE) .column(CHUNK_X_FIELD, getDataType(Integer.class)) .column(CHUNK_Y_FIELD, getDataType(Integer.class)) .column(CHUNK_Z_FIELD, getDataType(Integer.class)) .column(PLANET_X_FIELD, getDataType(Integer.class)) .column(PLANET_Y_FIELD, getDataType(Integer.class)) .column(PLANET_Z_FIELD, getDataType(Integer.class)) .column(PLANET_RADIUS_FIELD, getDataType(Integer.class)) .execute(); } }
@Override public final String getTableName(int column) throws SQLException { checkNotClosed(); Field<?> field = result.getField(column - 1); if (field instanceof TableField) { Table<?> table = ((TableField<?, ?>) field).getTable(); if (table != null) { return table.getName(); } } // By default, no table is available return ""; }
@SuppressWarnings("unchecked") public static <T extends UpdatableRecord<?>> T findById( DSLContext context, Class<T> clz, Object id) { if (id == null) return null; Table<?> table = getTableFromRecordClass(clz); if (table == null) return null; UniqueKey<?> key = table.getPrimaryKey(); if (key == null || key.getFieldsArray().length != 1) return null; TableField<?, Object> keyField = (TableField<?, Object>) key.getFieldsArray()[0]; /* Convert object because we are abusing type safety here */ Object converted = keyField.getDataType().convert(id); return (T) context.selectFrom(table).where(keyField.eq(converted)).fetchOne(); }
@Override public final <Z extends Record> Result<Z> into(Table<Z> table) { Result<Z> list = new ResultImpl<Z>(getConfiguration(), table.fields()); for (R record : this) { list.add(record.into(table)); } return list; }
@SuppressWarnings("unchecked") private final Merge<R> toMerge(Configuration configuration) { Table<R> i = getInto(); if (i.getPrimaryKey() != null) { Condition condition = null; List<Field<?>> key = new ArrayList<Field<?>>(); for (Field<?> f : i.getPrimaryKey().getFields()) { Field<Object> field = (Field<Object>) f; Field<Object> value = (Field<Object>) insertMaps.getMap().get(field); key.add(value); Condition other = field.equal(value); if (condition == null) { condition = other; } else { condition = condition.and(other); } } MergeOnConditionStep<R> on = create(configuration).mergeInto(i).usingDual().on(condition); // [#1295] Use UPDATE clause only when with ON DUPLICATE KEY UPDATE, // not with ON DUPLICATE KEY IGNORE MergeNotMatchedStep<R> notMatched = on; if (onDuplicateKeyUpdate) { notMatched = on.whenMatchedThenUpdate().set(updateMap); } return notMatched .whenNotMatchedThenInsert(insertMaps.getMap().keySet()) .values(insertMaps.getMap().values()); } else { throw new IllegalStateException( "The ON DUPLICATE KEY IGNORE/UPDATE clause cannot be simulated when inserting into non-updatable tables : " + getInto()); } }
@Override public final <O extends Record> List<ForeignKey<O, R>> getReferencesFrom(Table<O> other) { return other.getReferencesTo(this); }
public TableRecordImpl(Table<R> table) { super(table.fields()); this.table = table; }
/** Extracted method for type-safety */ private <Z> Condition condition(Table<?> pivot, Field<Z> field) { return field.equal(pivot.field(field)); }
private Table<Record> select(Configuration configuration) { List<Field<?>> groupingFields = new ArrayList<Field<?>>(); List<Field<?>> aliasedGroupingFields = new ArrayList<Field<?>>(); List<Field<?>> aggregatedFields = new ArrayList<Field<?>>(); Table<?> pivot = table.as("pivot_outer"); // Clearly, the API should be improved to make this more object- // oriented... // This loop finds all fields that are used in aggregate // functions. They're excluded from the GROUP BY clause for (Field<?> field : aggregateFunctions) { if (field instanceof Function) { for (QueryPart argument : ((Function<?>) field).getArguments()) { if (argument instanceof Field) { aggregatedFields.add((Field<?>) argument); } } } } // This loop finds all fields qualify for GROUP BY clauses for (Field<?> field : table.fields()) { if (!aggregatedFields.contains(field)) { if (!on.equals(field)) { aliasedGroupingFields.add(pivot.field(field)); groupingFields.add(field); } } } // The product {aggregateFunctions} x {in} List<Field<?>> aggregationSelects = new ArrayList<Field<?>>(); for (Field<?> inField : in) { for (Field<?> aggregateFunction : aggregateFunctions) { Condition join = trueCondition(); for (Field<?> field : groupingFields) { join = join.and(condition(pivot, field)); } @SuppressWarnings("unchecked") Select<?> aggregateSelect = using(configuration) .select(aggregateFunction) .from(table) .where(on.equal((Field<T>) inField)) .and(join); aggregationSelects.add( aggregateSelect.asField(inField.getName() + "_" + aggregateFunction.getName())); } } // This is the complete select Table<Record> select = using(configuration) .select(aliasedGroupingFields) .select(aggregationSelects) .from(pivot) .where(pivot.field(on).in(in.toArray(new Field[0]))) .groupBy(aliasedGroupingFields) .asTable(); return select; }
private final boolean knownTable(Table<?> table) { return table.fieldsRow().size() > 0; }