001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.storage.sql; 020 021import java.io.Serializable; 022 023import org.nuxeo.ecm.core.schema.types.Field; 024import org.nuxeo.ecm.core.schema.types.SimpleTypeImpl; 025import org.nuxeo.ecm.core.schema.types.Type; 026import org.nuxeo.ecm.core.schema.types.primitives.BinaryType; 027import org.nuxeo.ecm.core.schema.types.primitives.BooleanType; 028import org.nuxeo.ecm.core.schema.types.primitives.DateType; 029import org.nuxeo.ecm.core.schema.types.primitives.DoubleType; 030import org.nuxeo.ecm.core.schema.types.primitives.IntegerType; 031import org.nuxeo.ecm.core.schema.types.primitives.LongType; 032import org.nuxeo.ecm.core.schema.types.primitives.StringType; 033 034/** 035 * The database-level column types, including per-type parameters like length. 036 */ 037public class ColumnType implements Serializable { 038 039 private static final long serialVersionUID = 1L; 040 041 /** Length used internally to flag a string to use CLOB. */ 042 public static final int CLOB_LENGTH = 999999999; 043 044 public static final ColumnType STRING = new ColumnType(ColumnSpec.STRING); 045 046 public static final ColumnType CLOB = new ColumnType(ColumnSpec.STRING, CLOB_LENGTH); 047 048 public static final ColumnType BOOLEAN = new ColumnType(ColumnSpec.BOOLEAN); 049 050 public static final ColumnType LONG = new ColumnType(ColumnSpec.LONG); 051 052 public static final ColumnType DOUBLE = new ColumnType(ColumnSpec.DOUBLE); 053 054 public static final ColumnType TIMESTAMP = new ColumnType(ColumnSpec.TIMESTAMP); 055 056 public static final ColumnType BLOBID = new ColumnType(ColumnSpec.BLOBID); 057 058 public static final ColumnType BLOB = new ColumnType(ColumnSpec.BLOB); 059 060 public static final ColumnType ARRAY_STRING = new ColumnType(ColumnSpec.ARRAY_STRING, -1, true); 061 062 public static final ColumnType ARRAY_CLOB = new ColumnType(ColumnSpec.ARRAY_STRING, CLOB_LENGTH, true); 063 064 public static final ColumnType ARRAY_BOOLEAN = new ColumnType(ColumnSpec.ARRAY_BOOLEAN, -1, true); 065 066 public static final ColumnType ARRAY_LONG = new ColumnType(ColumnSpec.ARRAY_LONG, -1, true); 067 068 public static final ColumnType ARRAY_DOUBLE = new ColumnType(ColumnSpec.ARRAY_DOUBLE, -1, true); 069 070 public static final ColumnType ARRAY_TIMESTAMP = new ColumnType(ColumnSpec.ARRAY_TIMESTAMP, -1, true); 071 072 public static final ColumnType ARRAY_BLOBID = new ColumnType(ColumnSpec.ARRAY_BLOBID, -1, true); 073 074 public static final ColumnType ARRAY_INTEGER = new ColumnType(ColumnSpec.ARRAY_INTEGER, -1, true); 075 076 public static final ColumnType NODEID = new ColumnType(ColumnSpec.NODEID); 077 078 public static final ColumnType NODEIDFK = new ColumnType(ColumnSpec.NODEIDFK); 079 080 public static final ColumnType NODEIDFKNP = new ColumnType(ColumnSpec.NODEIDFKNP); 081 082 public static final ColumnType NODEIDFKMUL = new ColumnType(ColumnSpec.NODEIDFKMUL); 083 084 public static final ColumnType NODEIDFKNULL = new ColumnType(ColumnSpec.NODEIDFKNULL); 085 086 public static final ColumnType NODEIDPK = new ColumnType(ColumnSpec.NODEIDPK); 087 088 public static final ColumnType NODEVAL = new ColumnType(ColumnSpec.NODEVAL); 089 090 public static final ColumnType NODEARRAY = new ColumnType(ColumnSpec.NODEARRAY, -1, true); 091 092 public static final ColumnType SYSNAME = new ColumnType(ColumnSpec.SYSNAME); 093 094 public static final ColumnType SYSNAMEARRAY = new ColumnType(ColumnSpec.SYSNAMEARRAY, -1, true); 095 096 public static final ColumnType TINYINT = new ColumnType(ColumnSpec.TINYINT); 097 098 public static final ColumnType INTEGER = new ColumnType(ColumnSpec.INTEGER); 099 100 public static final ColumnType AUTOINC = new ColumnType(ColumnSpec.AUTOINC); 101 102 public static final ColumnType FTINDEXED = new ColumnType(ColumnSpec.FTINDEXED); 103 104 public static final ColumnType FTSTORED = new ColumnType(ColumnSpec.FTSTORED); 105 106 public static final ColumnType CLUSTERNODE = new ColumnType(ColumnSpec.CLUSTERNODE); 107 108 public static final ColumnType CLUSTERFRAGS = new ColumnType(ColumnSpec.CLUSTERFRAGS); 109 110 public final ColumnSpec spec; 111 112 public final int length; 113 114 public final boolean array; 115 116 public ColumnType(ColumnSpec spec, int length, boolean array) { 117 this.spec = spec; 118 this.length = length; 119 this.array = array; 120 } 121 122 public ColumnType(ColumnSpec spec, int length) { 123 this(spec, length, false); 124 } 125 126 public ColumnType(ColumnSpec spec) { 127 this(spec, -1); 128 } 129 130 public boolean isUnconstrained() { 131 return length == -1; 132 } 133 134 public boolean isClob() { 135 return length == CLOB_LENGTH; 136 } 137 138 public boolean isArray() { 139 return array; 140 } 141 142 /** 143 * Checks if this column holds a Nuxeo unique id (usually UUID). 144 */ 145 public boolean isId() { 146 return spec.isId(); 147 } 148 149 /** 150 * Wraps a string that needs to be mapped to an id column in prepared statements. 151 * 152 * @since 5.7 153 */ 154 public static class WrappedId implements Serializable { 155 private static final long serialVersionUID = 1L; 156 157 public final String string; 158 159 public WrappedId(String string) { 160 this.string = string; 161 } 162 163 @Override 164 public String toString() { 165 return string; 166 } 167 } 168 169 @Override 170 public String toString() { 171 if (isUnconstrained()) { 172 return spec.toString(); 173 } else if (isClob()) { 174 return isArray() ? "ARRAY_CLOB" : "CLOB"; 175 } else { 176 return spec.toString() + '(' + length + ')'; 177 } 178 } 179 180 /** 181 * Gets the column type from a Nuxeo Schema field, including its constrained length if any. 182 */ 183 public static ColumnType fromField(Field field) { 184 return fromFieldType(field.getType(), field.getMaxLength()); 185 } 186 187 /** 188 * Gets the column type from a Nuxeo Schema field type (unconstrained). 189 */ 190 public static ColumnType fromFieldType(Type type) { 191 return fromFieldType(type, -1); 192 } 193 194 /** 195 * Gets the column type from a Nuxeo Schema field type (unconstrained) with array {@code true} if an array type is 196 * required 197 */ 198 public static ColumnType fromFieldType(Type type, boolean array) { 199 return fromFieldType(type, -1, array); 200 } 201 202 protected static ColumnType fromFieldType(Type type, int maxLength) { 203 return fromFieldType(type, maxLength, false); 204 } 205 206 protected static ColumnType fromFieldType(Type type, int maxLength, boolean array) { 207 if (type instanceof StringType) { 208 if (maxLength == -1) { 209 return array ? ARRAY_STRING : STRING; // unconstrained 210 } else { 211 return new ColumnType(ColumnSpec.STRING, maxLength, array); 212 } 213 } else if (type instanceof BooleanType) { 214 return array ? ARRAY_BOOLEAN : BOOLEAN; 215 } else if (type instanceof LongType) { 216 return array ? ARRAY_LONG : LONG; 217 } else if (type instanceof DoubleType) { 218 return array ? ARRAY_DOUBLE : DOUBLE; 219 } else if (type instanceof DateType) { 220 return array ? ARRAY_TIMESTAMP : TIMESTAMP; 221 } else if (type instanceof BinaryType) { 222 return array ? ARRAY_BLOBID : BLOBID; 223 } else if (type instanceof IntegerType) { 224 return array ? ARRAY_INTEGER : INTEGER; 225 } else if (type instanceof SimpleTypeImpl) { 226 // comes from a constraint 227 return fromFieldType(type.getSuperType(), maxLength); 228 } else { 229 throw new RuntimeException("Invalid primitive type: " + type.getClass().getName()); 230 } 231 } 232 233}