CsvSchema now extends MapSchema, rather than implementing Schema directly. This removes a lot of code, and allows the schema to contain explicit tables, including views.
diff --git a/pom.xml b/pom.xml
index bf50031..4eef3ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,7 +82,7 @@
<dependency>
<groupId>net.hydromatic</groupId>
<artifactId>optiq</artifactId>
- <version>0.3.7</version>
+ <version>TRUNK-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.hydromatic</groupId>
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvSchema.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvSchema.java
index b6c9fa8..38dd4eb 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvSchema.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvSchema.java
@@ -17,13 +17,11 @@
*/
package net.hydromatic.optiq.impl.csv;
-import net.hydromatic.linq4j.*;
import net.hydromatic.linq4j.expressions.Expression;
import net.hydromatic.optiq.*;
import net.hydromatic.optiq.impl.TableInSchemaImpl;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
-import net.hydromatic.optiq.jdbc.OptiqConnection;
+import net.hydromatic.optiq.impl.java.MapSchema;
import org.eigenbase.reltype.RelDataType;
@@ -34,13 +32,9 @@
* Schema mapped onto a directory of CSV files. Each table in the schema
* is a CSV file in that directory.
*/
-public class CsvSchema implements Schema {
- private final Schema parentSchema;
+public class CsvSchema extends MapSchema {
final File directoryFile;
- private final Expression expression;
private final boolean smart;
- final JavaTypeFactory typeFactory;
- private Map<String, TableInSchema> map;
/**
* Creates a CSV schema.
@@ -58,83 +52,39 @@
Expression expression,
boolean smart)
{
- this.parentSchema = parentSchema;
+ super(parentSchema, expression);
this.directoryFile = directoryFile;
- this.expression = expression;
this.smart = smart;
- this.typeFactory = ((OptiqConnection) getQueryProvider()).getTypeFactory();
}
- public Expression getExpression() {
- return expression;
- }
-
- public List<TableFunction> getTableFunctions(String name) {
- return Collections.emptyList();
- }
-
- public QueryProvider getQueryProvider() {
- return parentSchema.getQueryProvider();
- }
-
- public Collection<TableInSchema> getTables() {
- return computeMap().values();
- }
-
- public <T> Table<T> getTable(String name, Class<T> elementType) {
- final TableInSchema tableInSchema = computeMap().get(name);
- //noinspection unchecked
- return tableInSchema == null
- ? null
- : (Table) tableInSchema.getTable(elementType);
- }
-
- public Map<String, List<TableFunction>> getTableFunctions() {
- // this kind of schema does not have table functions
- return Collections.emptyMap();
- }
-
- public Schema getSubSchema(String name) {
- // this kind of schema does not have sub-schemas
- return null;
- }
-
- public Collection<String> getSubSchemaNames() {
- // this kind of schema does not have sub-schemas
- return Collections.emptyList();
- }
-
- /** Returns the map of tables by name, populating the map on first use. */
- private synchronized Map<String, TableInSchema> computeMap() {
- if (map == null) {
- map = new HashMap<String, TableInSchema>();
- File[] files = directoryFile.listFiles(
- new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".csv");
- }
- });
- for (File file : files) {
- String tableName = file.getName();
- if (tableName.endsWith(".csv")) {
- tableName = tableName.substring(
- 0, tableName.length() - ".csv".length());
- }
- final List<CsvFieldType> fieldTypes = new ArrayList<CsvFieldType>();
- final RelDataType rowType =
- CsvTable.deduceRowType(typeFactory, file, fieldTypes);
- final CsvTable table;
- if (smart) {
- table = new CsvSmartTable(this, tableName, file, rowType, fieldTypes);
- } else {
- table = new CsvTable(this, tableName, file, rowType, fieldTypes);
- }
- map.put(
- tableName,
- new TableInSchemaImpl(this, tableName, TableType.TABLE, table));
+ @Override
+ protected Collection<TableInSchema> initialTables() {
+ final List<TableInSchema> list = new ArrayList<TableInSchema>();
+ File[] files = directoryFile.listFiles(
+ new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".csv");
+ }
+ });
+ for (File file : files) {
+ String tableName = file.getName();
+ if (tableName.endsWith(".csv")) {
+ tableName = tableName.substring(
+ 0, tableName.length() - ".csv".length());
}
+ final List<CsvFieldType> fieldTypes = new ArrayList<CsvFieldType>();
+ final RelDataType rowType =
+ CsvTable.deduceRowType(typeFactory, file, fieldTypes);
+ final CsvTable table;
+ if (smart) {
+ table = new CsvSmartTable(this, tableName, file, rowType, fieldTypes);
+ } else {
+ table = new CsvTable(this, tableName, file, rowType, fieldTypes);
+ }
+ list.add(
+ new TableInSchemaImpl(this, tableName, TableType.TABLE, table));
}
- return map;
+ return list;
}
}
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvSmartTable.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvSmartTable.java
index dca6e3a..b6abbee 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvSmartTable.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvSmartTable.java
@@ -23,7 +23,6 @@
import org.eigenbase.reltype.RelDataType;
import java.io.File;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -37,16 +36,6 @@
super(schema, tableName, file, rowType, fieldTypes);
}
- /** Creates a table based on a CSV file, deducing its column types by reading
- * the first line of the file. */
- public static CsvSmartTable create(CsvSchema schema, File file,
- String tableName) {
- final List<CsvFieldType> fieldTypes = new ArrayList<CsvFieldType>();
- final RelDataType rowType =
- deduceRowType(schema.typeFactory, file, fieldTypes);
- return new CsvSmartTable(schema, tableName, file, rowType, fieldTypes);
- }
-
public RelNode toRel(
RelOptTable.ToRelContext context,
RelOptTable relOptTable)
diff --git a/src/test/resources/model-with-view.json b/src/test/resources/model-with-view.json
new file mode 100644
index 0000000..8174a3f
--- /dev/null
+++ b/src/test/resources/model-with-view.json
@@ -0,0 +1,21 @@
+{
+ version: '1.0',
+ defaultSchema: 'SALES',
+ schemas: [
+ {
+ name: 'SALES',
+ type: 'custom',
+ factory: 'net.hydromatic.optiq.impl.csv.CsvSchemaFactory',
+ operand: {
+ directory: 'target/test-classes/sales'
+ },
+ tables: [
+ {
+ name: 'FEMALE_EMPS',
+ type: 'view',
+ sql: 'SELECT * FROM emps WHERE gender = \'F\''
+ }
+ ]
+ }
+ ]
+}