001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to you under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package gudusoft.gsqlparser.ext.calcite.catalog.impl; 018 019import gudusoft.gsqlparser.ext.calcite.catalog.Catalog; 020import gudusoft.gsqlparser.ext.calcite.catalog.Column; 021import gudusoft.gsqlparser.ext.calcite.catalog.Schema; 022import gudusoft.gsqlparser.ext.calcite.catalog.Table; 023 024import org.checkerframework.checker.nullness.qual.Nullable; 025 026import java.util.ArrayList; 027import java.util.LinkedHashMap; 028import java.util.List; 029import java.util.Map; 030 031import static java.util.Objects.requireNonNull; 032 033/** 034 * Simple, mutable implementation of {@link Catalog}. 035 * 036 * <p>This implementation uses LinkedHashMap to maintain insertion order. 037 */ 038public class SimpleCatalog implements Catalog { 039 private final String name; 040 private final Map<String, SimpleSchema> schemas; 041 private @Nullable String defaultSchemaName; 042 043 public SimpleCatalog(String name) { 044 this.name = requireNonNull(name, "name"); 045 this.schemas = new LinkedHashMap<>(); 046 } 047 048 @Override public String getName() { 049 return name; 050 } 051 052 @Override public List<Schema> getSchemas() { 053 return new ArrayList<>(schemas.values()); 054 } 055 056 @Override public @Nullable Schema getSchema(String schemaName) { 057 return schemas.get(schemaName); 058 } 059 060 @Override public List<String> getSchemaNames() { 061 return new ArrayList<>(schemas.keySet()); 062 } 063 064 @Override public @Nullable Table getTable(String schemaName, String tableName) { 065 Schema schema = getSchema(schemaName); 066 return schema == null ? null : schema.getTable(tableName); 067 } 068 069 @Override public @Nullable String getDefaultSchemaName() { 070 return defaultSchemaName; 071 } 072 073 /** 074 * Adds a schema to this catalog. 075 * 076 * @param schema Schema to add 077 * @return This catalog (for chaining) 078 */ 079 public SimpleCatalog addSchema(SimpleSchema schema) { 080 schemas.put(schema.getName(), schema); 081 return this; 082 } 083 084 /** 085 * Creates and adds a new schema to this catalog. 086 * 087 * @param schemaName Schema name 088 * @return The newly created schema 089 */ 090 public SimpleSchema createSchema(String schemaName) { 091 SimpleSchema schema = new SimpleSchema(schemaName, this); 092 addSchema(schema); 093 return schema; 094 } 095 096 /** 097 * Sets the default schema name. 098 * 099 * @param defaultSchemaName Default schema name 100 * @return This catalog (for chaining) 101 */ 102 public SimpleCatalog setDefaultSchemaName(String defaultSchemaName) { 103 this.defaultSchemaName = defaultSchemaName; 104 return this; 105 } 106 107 /** 108 * Simple, mutable implementation of {@link Schema}. 109 */ 110 public static class SimpleSchema implements Schema { 111 private final String name; 112 private final SimpleCatalog catalog; 113 private final Map<String, SimpleTable> tables; 114 115 public SimpleSchema(String name, SimpleCatalog catalog) { 116 this.name = requireNonNull(name, "name"); 117 this.catalog = requireNonNull(catalog, "catalog"); 118 this.tables = new LinkedHashMap<>(); 119 } 120 121 @Override public String getName() { 122 return name; 123 } 124 125 @Override public Catalog getCatalog() { 126 return catalog; 127 } 128 129 @Override public List<Table> getTables() { 130 return new ArrayList<>(tables.values()); 131 } 132 133 @Override public @Nullable Table getTable(String tableName) { 134 return tables.get(tableName); 135 } 136 137 @Override public List<String> getTableNames() { 138 return new ArrayList<>(tables.keySet()); 139 } 140 141 /** 142 * Adds a table to this schema. 143 * 144 * @param table Table to add 145 * @return This schema (for chaining) 146 */ 147 public SimpleSchema addTable(SimpleTable table) { 148 tables.put(table.getName(), table); 149 return this; 150 } 151 152 /** 153 * Creates and adds a new table to this schema. 154 * 155 * @param tableName Table name 156 * @param tableType Table type (e.g., "TABLE", "VIEW") 157 * @return The newly created table 158 */ 159 public SimpleTable createTable(String tableName, String tableType) { 160 SimpleTable table = new SimpleTable(tableName, tableType, this); 161 addTable(table); 162 return table; 163 } 164 165 /** 166 * Creates and adds a new table to this schema with type "TABLE". 167 * 168 * @param tableName Table name 169 * @return The newly created table 170 */ 171 public SimpleTable createTable(String tableName) { 172 return createTable(tableName, "TABLE"); 173 } 174 } 175 176 /** 177 * Simple, mutable implementation of {@link Table}. 178 */ 179 public static class SimpleTable implements Table { 180 private final String name; 181 private final String tableType; 182 private final SimpleSchema schema; 183 private final Map<String, SimpleColumn> columns; 184 private final List<String> primaryKeys; 185 private @Nullable String comment; 186 187 public SimpleTable(String name, String tableType, SimpleSchema schema) { 188 this.name = requireNonNull(name, "name"); 189 this.tableType = requireNonNull(tableType, "tableType"); 190 this.schema = requireNonNull(schema, "schema"); 191 this.columns = new LinkedHashMap<>(); 192 this.primaryKeys = new ArrayList<>(); 193 } 194 195 @Override public String getName() { 196 return name; 197 } 198 199 @Override public String getTableType() { 200 return tableType; 201 } 202 203 @Override public Schema getSchema() { 204 return schema; 205 } 206 207 @Override public List<Column> getColumns() { 208 return new ArrayList<>(columns.values()); 209 } 210 211 @Override public @Nullable Column getColumn(String columnName) { 212 return columns.get(columnName); 213 } 214 215 @Override public @Nullable String getComment() { 216 return comment; 217 } 218 219 @Override public List<String> getPrimaryKeys() { 220 return new ArrayList<>(primaryKeys); 221 } 222 223 /** 224 * Adds a column to this table. 225 * 226 * @param column Column to add 227 * @return This table (for chaining) 228 */ 229 public SimpleTable addColumn(SimpleColumn column) { 230 columns.put(column.getName(), column); 231 return this; 232 } 233 234 /** 235 * Creates and adds a new column to this table. 236 * 237 * @param columnName Column name 238 * @param typeName SQL type name 239 * @param nullable Whether the column is nullable 240 * @return The newly created column 241 */ 242 public SimpleColumn createColumn(String columnName, String typeName, boolean nullable) { 243 int ordinal = columns.size() + 1; 244 SimpleColumn column = new SimpleColumn(columnName, typeName, ordinal, nullable); 245 addColumn(column); 246 return column; 247 } 248 249 /** 250 * Sets the comment for this table. 251 * 252 * @param comment Table comment 253 * @return This table (for chaining) 254 */ 255 public SimpleTable setComment(String comment) { 256 this.comment = comment; 257 return this; 258 } 259 260 /** 261 * Sets the primary key columns. 262 * 263 * @param primaryKeys Primary key column names 264 * @return This table (for chaining) 265 */ 266 public SimpleTable setPrimaryKeys(List<String> primaryKeys) { 267 this.primaryKeys.clear(); 268 this.primaryKeys.addAll(primaryKeys); 269 return this; 270 } 271 272 /** 273 * Adds a primary key column. 274 * 275 * @param columnName Primary key column name 276 * @return This table (for chaining) 277 */ 278 public SimpleTable addPrimaryKey(String columnName) { 279 this.primaryKeys.add(columnName); 280 return this; 281 } 282 } 283 284 /** 285 * Simple, mutable implementation of {@link Column}. 286 */ 287 public static class SimpleColumn implements Column { 288 private final String name; 289 private final String typeName; 290 private final int ordinalPosition; 291 private final boolean nullable; 292 private @Nullable Integer size; 293 private @Nullable Integer decimalDigits; 294 private @Nullable String defaultValue; 295 private @Nullable String comment; 296 297 public SimpleColumn(String name, String typeName, int ordinalPosition, boolean nullable) { 298 this.name = requireNonNull(name, "name"); 299 this.typeName = requireNonNull(typeName, "typeName"); 300 this.ordinalPosition = ordinalPosition; 301 this.nullable = nullable; 302 } 303 304 @Override public String getName() { 305 return name; 306 } 307 308 @Override public String getTypeName() { 309 return typeName; 310 } 311 312 @Override public int getOrdinalPosition() { 313 return ordinalPosition; 314 } 315 316 @Override public boolean isNullable() { 317 return nullable; 318 } 319 320 @Override public @Nullable Integer getSize() { 321 return size; 322 } 323 324 @Override public @Nullable Integer getDecimalDigits() { 325 return decimalDigits; 326 } 327 328 @Override public @Nullable String getDefaultValue() { 329 return defaultValue; 330 } 331 332 @Override public @Nullable String getComment() { 333 return comment; 334 } 335 336 /** 337 * Sets the size of the column. 338 * 339 * @param size Column size 340 * @return This column (for chaining) 341 */ 342 public SimpleColumn setSize(Integer size) { 343 this.size = size; 344 return this; 345 } 346 347 /** 348 * Sets the decimal digits of the column. 349 * 350 * @param decimalDigits Decimal digits 351 * @return This column (for chaining) 352 */ 353 public SimpleColumn setDecimalDigits(Integer decimalDigits) { 354 this.decimalDigits = decimalDigits; 355 return this; 356 } 357 358 /** 359 * Sets the default value of the column. 360 * 361 * @param defaultValue Default value 362 * @return This column (for chaining) 363 */ 364 public SimpleColumn setDefaultValue(String defaultValue) { 365 this.defaultValue = defaultValue; 366 return this; 367 } 368 369 /** 370 * Sets the comment for the column. 371 * 372 * @param comment Column comment 373 * @return This column (for chaining) 374 */ 375 public SimpleColumn setComment(String comment) { 376 this.comment = comment; 377 return this; 378 } 379 } 380}