All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.firebirdsql.gds.ng.fields.RowDescriptorBuilder Maven / Gradle / Ivy

There is a newer version: 6.0.0-beta-1
Show newest version
/*
 * Firebird Open Source JDBC Driver
 *
 * Distributable under LGPL license.
 * You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * LGPL License for more details.
 *
 * This file was created by members of the firebird development team.
 * All individual contributions remain the Copyright (C) of those
 * individuals.  Contributors to this file are either listed here or
 * can be obtained from a source control history command.
 *
 * All rights reserved.
 */
package org.firebirdsql.gds.ng.fields;

import org.firebirdsql.gds.ng.DatatypeCoder;

/**
 * Builder to construct an immutable {@link RowDescriptor}.
 * 

* The row descriptor is constructed by defining the fields, and using {@link #addField()} to add the current field * definition to the row. The field data is then reset (as if {@link #resetField()} was called, * to prepare for the next field to add. *

*

* This class can also be used to construct individual {@link FieldDescriptor} objects. *

* * @author Mark Rotteveel * @since 3.0 */ public final class RowDescriptorBuilder { private final DatatypeCoder datatypeCoder; private int type; private int subType; private int scale; private int length; private String fieldName; private String tableAlias; private String originalName; private String originalTableName; private String ownerName; private final FieldDescriptor[] fieldDescriptors; private int currentFieldIndex; /** * Constructs an instance of RowDescriptorBuilder for size fields. * * @param size * Number of fields * @param datatypeCoder * DatatypeCoder for decoding field data */ public RowDescriptorBuilder(final int size, DatatypeCoder datatypeCoder) { this.datatypeCoder = datatypeCoder; fieldDescriptors = new FieldDescriptor[size]; } /** * @return Number of fields the row will hold. */ public int getSize() { return fieldDescriptors.length; } /** * Set the Firebird data type of the field. * * @param type * Data type * @return this builder */ public RowDescriptorBuilder setType(final int type) { this.type = type; return this; } /** * Set the Firebird subtype of the field. * * @param subType * Subtype * @return this builder * @see #setType(int) */ public RowDescriptorBuilder setSubType(final int subType) { this.subType = subType; return this; } /** * Set the scale of the field. * * @param scale * Scale * @return this builder * @see #setType(int) */ public RowDescriptorBuilder setScale(final int scale) { this.scale = scale; return this; } /** * Set the defined length of the field. * * @param length * Defined (maximum) length of the field * @return this builder */ public RowDescriptorBuilder setLength(final int length) { this.length = length; return this; } /** * Sets the (aliased) field name. * * @param fieldName * The field name * @return this builder * @see #setOriginalName(String) */ public RowDescriptorBuilder setFieldName(final String fieldName) { this.fieldName = fieldName; return this; } /** * Sets the alias of the underlying table. * * @param tableAlias * The table alias * @return this builder * @see #setOriginalTableName(String) */ public RowDescriptorBuilder setTableAlias(final String tableAlias) { this.tableAlias = tableAlias; return this; } /** * Sets the original field name. * * @param originalName * The original field name * @return this builder * @see #setFieldName(String) */ public RowDescriptorBuilder setOriginalName(final String originalName) { this.originalName = originalName; return this; } /** * Sets the original name of the underlying table. * * @param originalTableName * The table name * @return this builder * @see #setTableAlias(String) */ public RowDescriptorBuilder setOriginalTableName(final String originalTableName) { this.originalTableName = originalTableName; return this; } /** * Sets the field index for the current field under construction. *

* Even though {@link #addField()} increments the current field index, it is advisable to always explicitly * set the index using this method or {@link #at(int)} as it improves readability. *

* * @param index * Index of the field * @return this builder * @throws IndexOutOfBoundsException * When index is not between 0 (inclusive) and {@link #getSize()} (exclusive) * @throws IllegalStateException * When a {@link FieldDescriptor} is already defined on the specified index */ public RowDescriptorBuilder setFieldIndex(final int index) { if (index < 0 || index >= fieldDescriptors.length) { throw new IndexOutOfBoundsException(String.format("The index '%d' exceeds the expected size (%d) of this RowDescriptorBuilder", index, fieldDescriptors.length)); } if (fieldDescriptors[index] != null) { throw new IllegalStateException(String.format("There is already a field at index '%d'", index)); } currentFieldIndex = index; return this; } /** * Convenience shortcut for {@link #setFieldIndex(int)}. * * @param index * Index of the field * @return this builder * @see #setFieldIndex(int) */ public RowDescriptorBuilder at(final int index) { return setFieldIndex(index); } /** * @return The index for the current field */ public int getCurrentFieldIndex() { return currentFieldIndex; } /** * Sets the owner (database username) of the field. * * @param ownerName * Name of the owner * @return this builder */ public RowDescriptorBuilder setOwnerName(final String ownerName) { this.ownerName = ownerName; return this; } /** * Convenience method to populate the basic field information used in metadata result sets (e.g. for use in * {@link org.firebirdsql.jdbc.FBDatabaseMetaData}). * * @param type * Firebird data type * @param length * Defined (maximum) length of the field * @param originalName * The original field name * @param originalTableName * The table name * @return this builder * @see #setType(int) * @see #setLength(int) * @see #setOriginalTableName(String) * @see #setOriginalName(String) */ public RowDescriptorBuilder simple(final int type, final int length, final String originalName, final String originalTableName) { this.type = type; this.length = length; this.originalName = originalName; this.originalTableName = originalTableName; return this; } /** * Creates a {@link FieldDescriptor} based on the current field data of this RowDescriptorBuilder. * * @return FieldDescriptor */ public FieldDescriptor toFieldDescriptor() { return new FieldDescriptor(currentFieldIndex, datatypeCoder, type, subType, scale, length, fieldName, tableAlias, originalName, originalTableName, ownerName); } /** * Resets the fields of this builder to the Java defaults. */ public RowDescriptorBuilder resetField() { type = 0; subType = 0; scale = 0; length = 0; fieldName = null; tableAlias = null; originalName = null; originalTableName = null; ownerName = null; return this; } /** * Set this builder with the values of the source {@link FieldDescriptor} for further modification through this builder. * * @param sourceFieldDescriptor * Source for the initial values * @return this builder */ public RowDescriptorBuilder copyFieldFrom(final FieldDescriptor sourceFieldDescriptor) { type = sourceFieldDescriptor.getType(); subType = sourceFieldDescriptor.getSubType(); scale = sourceFieldDescriptor.getScale(); length = sourceFieldDescriptor.getLength(); fieldName = sourceFieldDescriptor.getFieldName(); tableAlias = sourceFieldDescriptor.getTableAlias(); originalName = sourceFieldDescriptor.getOriginalName(); originalTableName = sourceFieldDescriptor.getOriginalTableName(); ownerName = sourceFieldDescriptor.getOwnerName(); return this; } /** * Adds the current field data to the row and prepares this builder for the next field by resetting all values. * * @return this builder * @see #resetField() */ public RowDescriptorBuilder addField() { return addField(toFieldDescriptor()).resetField(); } /** * Adds the {@link FieldDescriptor} on the current fieldIndex as the next in the row, and increments the current * field index by 1. *

* This method does not call {@link #resetField()}, so a partial definition of a field can exist * inside this builder after calling this method. *

* * @param fieldDescriptor * FieldDescriptor to add * @return this builder */ public RowDescriptorBuilder addField(final FieldDescriptor fieldDescriptor) { if (currentFieldIndex >= fieldDescriptors.length) { throw new IndexOutOfBoundsException(String.format("The index '%d' exceeds the expected size (%d) of this RowDescriptorBuilder", currentFieldIndex, fieldDescriptors.length)); } fieldDescriptors[currentFieldIndex] = fieldDescriptor; currentFieldIndex += 1; return this; } /** * Constructs the {@link RowDescriptor} with the current content. *

* This method can also return a partially filled {@link RowDescriptor}. Caller can check for completeness by * calling {@link #isComplete()}. *

* * @return RowDescriptor instance. * @see #isComplete() */ public RowDescriptor toRowDescriptor() { // NOTE: The correctness of this depends on the fact that RowDescriptor copies the content of the array return RowDescriptor.createRowDescriptor(fieldDescriptors, datatypeCoder); } /** * @return true when all {@link FieldDescriptor} entries have been defined */ public boolean isComplete() { for (FieldDescriptor fieldDescriptor : fieldDescriptors) { if (fieldDescriptor == null) { return false; } } return true; } /** * @return Returns the index of the first unprocessed FieldDescriptor, or {@link #getSize()} if all fields have been set. */ public int getFirstUnprocessedIndex() { for (int idx = 0; idx < fieldDescriptors.length; idx++) { if (fieldDescriptors[idx] == null) { return idx; } } return getSize(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy