DbColumn.java
/*
* Copyright (C) 2000 - 2024 Silverpeas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* As a special exception to the terms and conditions of version 3.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* Open Source Software ("FLOSS") applications as described in Silverpeas's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* "https://www.silverpeas.org/legal/floss_exception.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
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.silverpeas.components.mydb.model;
import org.silverpeas.kernel.logging.SilverLogger;
import java.sql.JDBCType;
import java.sql.Types;
import java.util.Objects;
import java.util.stream.Stream;
import static org.silverpeas.kernel.util.StringUtil.isDefined;
/**
* A column in a database table. The column doesn't contain any values, it defines the column in
* a {@link DbTable} instance by a name and a type.
* @author mmoquillon
*/
public class DbColumn {
private final JdbcRequester.ColumnDescriptor descriptor;
/**
* Constructs a new {@link DbColumn} instance of the specified SQL type and with the specified
* name.
* @param descriptor a descriptor of the column.
*/
DbColumn(final JdbcRequester.ColumnDescriptor descriptor) {
this.descriptor = descriptor;
}
/**
* Gets the SQL type of the values this column can contain. The values are define by the
* {@link java.sql.Types} class.
* @return an integer identifying a generic SQL type.
*/
public int getType() {
return descriptor.getType();
}
/**
* Gets the name of this column.
* @return the column's name.
*/
public String getName() {
return descriptor.getName();
}
/**
* Gets the name of the SQL type of the values this column can contain. The name is determined
* from the SQL type code by using the {@link JDBCType} class.
* @return the name of the column's SQL type (VARCHAR, TIMESTAMP, ...)
*/
public String getTypeName() {
return JDBCType.valueOf(getType()).getName();
}
/**
* Gets the size of this column. It depends on its type; for example for VARCHAR(256), its
* size is 256.
* @return the size of this column according to its type.
*/
public int getSize() {
int size = descriptor.getSize();
if (getType() == Types.BIT && descriptor.getSize() == 1) {
size = "false".length();
}
return size;
}
/**
* Is this column represents a primary key?
* @return true if the values in this column are or are part of a primary key. False otherwise.
*/
public boolean isPrimaryKey() {
return descriptor.isPrimaryKey();
}
/**
* Is this column references a column of another table. If true, then the column takes part of
* a foreign key whose name is given by the {@link DbColumn#getName()} method.
* @return true if the values in this column are the primary keys of another table. False
* otherwise.
*/
public boolean isForeignKey() {
return descriptor.getForeignKey() != null;
}
/**
* Gets the name of the foreign key to which this column is a component. Several columns can
* be part of the same foreign key; in this case, the foreign key name is a way to figure out
* them.
* If this column isn't a foreign key, then {@link NullPointerException} is thrown.
* @return the unique foreign key name.
*/
public String getForeignKeyName() {
Objects.requireNonNull(descriptor.getForeignKey());
return descriptor.getForeignKey().getName();
}
/**
* Gets the column that is referenced by this column if this column is a foreign key.
* If this column isn't a foreign key, then {@link NullPointerException} is thrown.
* @return the name of the column referenced by this foreign key.
*/
public String getReferencedColumn() {
Objects.requireNonNull(descriptor.getForeignKey());
return descriptor.getForeignKey().getTargetColumnName();
}
/**
* Gets the table that is referenced by this column if this column is a foreign key.
* If this column isn't a foreign key, then {@link NullPointerException} is thrown.
* @return the name of the table referenced by this foreign key.
*/
public String getReferencedTable() {
Objects.requireNonNull(descriptor.getForeignKey());
return descriptor.getForeignKey().getTargetTableName();
}
/**
* Is this column accepts null values?
* @return true if this column is nullable. False otherwise.
*/
public boolean isNullable() {
return descriptor.isNullable();
}
/**
* Is the valuation of this column autogenerated when a new tuple is inserted into the table?
* @return true if this column is auto-valuated by the database when a row is newly inserted into
* the table this column belongs to.
*/
public boolean isAutoValued() {
return descriptor.isAutoIncrementable();
}
/**
* Is there a default value defined for this column?
* @return true if a default value is defined for this column, false otherwise.
*/
public boolean isDefaultValueDefined() {
return this.descriptor.getDefaultValue().isDefined();
}
/**
* Gets the String representation of the value by default of this column when no one is
* explicitly set.
* @return as a {@link String} the default value of this column.
*/
public String getDefaultValue() {
return this.descriptor.getDefaultValue().get();
}
/**
* Is this column is of type text (VARCHAR, CLOB, ...)?
* @return true if the values of this column are textual. False otherwise.
*/
public boolean isOfTypeText() {
return SqlTypes.isText(getType());
}
/**
* Is this column is of type binary (BLOB, VARBINARY, ...)?
* @return true if the values of this column are binary. False otherwise.
*/
public boolean isOfTypeBinary() {
return SqlTypes.isBinary(getType());
}
/**
* Gets a JDBC value of given value. The aim is to get a value to fill into
* JDBC query criteria filters.
* <p>
* Comma character is used to define a list of values.
* </p>
* @param value a value to convert.
* @return a JDBC value according to the SQL type of the column.
*/
public Object getJdbcValueOf(final String value) {
try {
if (isDefined(value)) {
final Object[] values = Stream
.of(value.replace("\\,", "\\@@##@@").split(","))
.map(v -> v.replace("\\@@##@@", "\\,"))
.map(v -> TableFieldValue.fromString(v, getType()).toSQLObject())
.toArray();
return values.length == 1 ? values[0] : values;
}
} catch (final Exception e) {
SilverLogger.getLogger(this).warn(e);
}
return value;
}
}