package com.tesora.dve.sql.schema; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * 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 <http://www.gnu.org/licenses/>. * #L% */ import com.tesora.dve.errmap.AvailableErrors; import com.tesora.dve.errmap.ErrorInfo; import com.tesora.dve.sql.SchemaException; import com.tesora.dve.sql.ParserException.Pass; import com.tesora.dve.sql.node.expression.TableInstance; import com.tesora.dve.sql.util.UnaryProcedure; public class TableResolver { private boolean mtchecks = false; private UnaryProcedure<Database<?>> onDatabase = null; private String qualifiedMissingDBFormat = "No such database: '%s'"; private String unqualifiedMissingDBFormat = "No database specified (unqualified name)"; private MissingTableFunction missingTable = null; public TableResolver() { } public TableResolver withMTChecks() { mtchecks = true; return this; } public TableResolver withDatabaseFunction(UnaryProcedure<Database<?>> f) { onDatabase = f; return this; } // accepts a single string public TableResolver withQualifiedMissingDBFormat(String fmt) { qualifiedMissingDBFormat = fmt; return this; } public TableResolver withUnqualifiedMissingDBFormat(String fmt) { unqualifiedMissingDBFormat = fmt; return this; } public TableResolver withMissingTableFunction(MissingTableFunction f) { missingTable = f; return this; } // for resolution. unifying this down to one spot to handle temporary tables correctly. public TableInstance lookupTable(SchemaContext sc, Name n, LockInfo lockType) { TableInstance raw = sc.getTemporaryTableSchema().buildInstance(sc, n); if (raw != null) return raw; Database<?> db = null; UnqualifiedName tableName = null; if (n.isQualified()) { QualifiedName qname = (QualifiedName) n; UnqualifiedName ofdb = qname.getNamespace(); tableName = qname.getUnqualified(); db = sc.findDatabase(ofdb); if (db == null) throw new SchemaException(Pass.SECOND, String.format(qualifiedMissingDBFormat, ofdb.getUnquotedName().get())); } else { tableName = (UnqualifiedName) n; db = sc.getCurrentDatabase(false); if (db == null) throw new SchemaException(new ErrorInfo(AvailableErrors.NO_DATABASE_SELECTED)); } if (onDatabase != null) onDatabase.execute(db); Schema<?> schema = db.getSchema(); raw = schema.buildInstance(sc,tableName.getUnqualified(), lockType, mtchecks); if (raw == null && missingTable != null) missingTable.onMissingTable(sc, schema, n); return raw; } public TableInstance lookupShowTable(SchemaContext sc, Schema<?> inSchema, Name n, LockInfo lockType) { Name tableName = n; Schema<?> schema = inSchema; if (tableName.isQualified()) { QualifiedName qname = (QualifiedName) tableName; UnqualifiedName ofdb = qname.getNamespace(); tableName = qname.getUnqualified(); Database<?> db = sc.findDatabase(ofdb); if (db == null) throw new SchemaException(Pass.SECOND, "No such database: '" + ofdb + "'"); schema = db.getSchema(); if (schema == null) throw new SchemaException(Pass.SECOND, "No database specified (qualified name)"); } if (schema == null) throw new SchemaException(Pass.SECOND, "No database specified (unqualified name)"); TableInstance raw = schema.buildInstance(sc,tableName.getUnqualified(), lockType); return raw; } public interface MissingTableFunction { public void onMissingTable(SchemaContext sc, Schema<?> schema, Name name); } }