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