package com.zendesk.maxwell.schema.columndef; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonSerialize(using=ColumnDefSerializer.class) @JsonDeserialize(using=ColumnDefDeserializer.class) public abstract class ColumnDef { protected String name; protected String type; protected int pos; public ColumnDef() { } public ColumnDef(String name, String type, int pos) { this.name = name; this.type = type; this.pos = pos; } public abstract boolean matchesMysqlType(int type); public abstract String toSQL(Object value); public Object asJSON(Object value) { return value; } public static ColumnDef build(String name, String charset, String type, int pos, boolean signed, String enumValues[], Long columnLength) { switch(type) { case "tinyint": case "smallint": case "mediumint": case "int": return new IntColumnDef(name, type, pos, signed); case "bigint": return new BigIntColumnDef(name, type, pos, signed); case "tinytext": case "text": case "mediumtext": case "longtext": case "varchar": case "char": return new StringColumnDef(name, type, pos, charset); case "tinyblob": case "blob": case "mediumblob": case "longblob": case "binary": case "varbinary": return new StringColumnDef(name, type, pos, "binary"); case "geometry": case "geometrycollection": case "linestring": case "multilinestring": case "multipoint": case "multipolygon": case "polygon": case "point": return new GeometryColumnDef(name, type, pos); case "float": case "double": return new FloatColumnDef(name, type, pos); case "decimal": return new DecimalColumnDef(name, type, pos); case "date": return new DateColumnDef(name, type, pos); case "datetime": case "timestamp": return new DateTimeColumnDef(name, type, pos, columnLength); case "time": return new TimeColumnDef(name, type, pos, columnLength); case "year": return new YearColumnDef(name, type, pos); case "enum": return new EnumColumnDef(name, type, pos, enumValues); case "set": return new SetColumnDef(name, type, pos, enumValues); case "bit": return new BitColumnDef(name, type, pos); case "json": return new JsonColumnDef(name, type, pos); default: throw new IllegalArgumentException("unsupported column type " + type); } } static private String charToByteType(String type) { switch (type) { case "char": case "character": return "binary"; case "varchar": case "varying": return "varbinary"; case "tinytext": return "tinyblob"; case "text": return "blob"; case "mediumtext": return "mediumblob"; case "longtext": return "longblob"; case "long": return "mediumblob"; default: throw new RuntimeException("Unknown type with BYTE flag: " + type); } } static public String unalias_type(String type, boolean longStringFlag, Long columnLength, boolean byteFlagToStringColumn) { if ( byteFlagToStringColumn ) type = charToByteType(type); if ( longStringFlag ) { switch (type) { case "varchar": return "mediumtext"; case "varbinary": return "mediumblob"; case "binary": return "mediumtext"; } } switch(type) { case "character": case "nchar": return "char"; case "text": case "blob": if ( columnLength == null ) return type; if ( columnLength < (1 << 8) ) return "tiny" + type; else if ( columnLength < ( 1 << 16) ) return type; else if ( columnLength < ( 1 << 24) ) return "medium" + type; else return "long" + type; case "nvarchar": case "varying": return "varchar"; case "bool": case "boolean": case "int1": return "tinyint"; case "int2": return "smallint"; case "int3": return "mediumint"; case "int4": case "integer": return "int"; case "int8": case "serial": return "bigint"; case "real": case "numeric": return "double"; case "long": return "mediumtext"; default: return type; } } public void setName(String name) { this.name = name; } public String getName() { return name; } public String getType() { return type; } public int getPos() { return pos; } public void setPos(int i) { this.pos = i; } }