22
22
import org .apache .calcite .schema .Schema ;
23
23
import org .apache .calcite .schema .SchemaPlus ;
24
24
import org .apache .calcite .schema .Schemas ;
25
+ import org .apache .calcite .schema .Table ;
25
26
import org .apache .calcite .schema .Wrapper ;
26
- import org .apache .calcite .schema .impl .AbstractSchema ;
27
+ import org .apache .calcite .schema .lookup .IgnoreCaseLookup ;
28
+ import org .apache .calcite .schema .lookup .LikePattern ;
29
+ import org .apache .calcite .schema .lookup .LoadingCacheLookup ;
30
+ import org .apache .calcite .schema .lookup .Lookup ;
27
31
import org .apache .calcite .sql .SqlDialect ;
28
32
import org .apache .calcite .sql .SqlDialectFactory ;
29
33
import org .apache .calcite .sql .SqlDialectFactoryImpl ;
30
34
import org .apache .calcite .util .BuiltInMethod ;
31
35
32
36
import com .google .common .base .Suppliers ;
33
- import com .google .common .collect .ImmutableMap ;
37
+ import com .google .common .collect .ImmutableSet ;
34
38
35
39
import org .checkerframework .checker .nullness .qual .Nullable ;
36
40
37
41
import java .sql .Connection ;
38
42
import java .sql .ResultSet ;
39
43
import java .sql .SQLException ;
40
- import java .util .Map ;
44
+ import java .util .Optional ;
45
+ import java .util .Set ;
41
46
import java .util .function .Supplier ;
42
47
import javax .sql .DataSource ;
43
48
51
56
* an instance of {@link JdbcSchema}.
52
57
*
53
58
* <p>This schema is lazy: it does not compute the list of schema names until
54
- * the first call to {@link #getSubSchemaMap( )}. Then it creates a
55
- * {@link JdbcSchema} for each schema name. Each JdbcSchema will populate its
59
+ * the first call to {@link #subSchemas()} and {@link Lookup#get(String )}. Then it creates a
60
+ * {@link JdbcSchema} for this schema name. Each JdbcSchema will populate its
56
61
* tables on demand.
57
62
*/
58
- public class JdbcCatalogSchema extends AbstractSchema implements Wrapper {
63
+ public class JdbcCatalogSchema extends JdbcBaseSchema implements Wrapper {
59
64
final DataSource dataSource ;
60
65
public final SqlDialect dialect ;
61
66
final JdbcConvention convention ;
62
67
final String catalog ;
68
+ private final Lookup <JdbcSchema > subSchemas ;
63
69
64
- /** Sub-schemas by name, lazily initialized. */
70
+ /** default schema name, lazily initialized. */
65
71
@ SuppressWarnings ({"method.invocation.invalid" , "Convert2MethodRef" })
66
- final Supplier <SubSchemaMap > subSchemaMapSupplier =
67
- Suppliers .memoize (() -> computeSubSchemaMap ( ));
72
+ private final Supplier <Optional < String >> defaultSchemaName =
73
+ Suppliers .memoize (() -> Optional . ofNullable ( computeDefaultSchemaName () ));
68
74
69
75
/** Creates a JdbcCatalogSchema. */
70
76
public JdbcCatalogSchema (DataSource dataSource , SqlDialect dialect ,
@@ -73,6 +79,40 @@ public JdbcCatalogSchema(DataSource dataSource, SqlDialect dialect,
73
79
this .dialect = requireNonNull (dialect , "dialect" );
74
80
this .convention = requireNonNull (convention , "convention" );
75
81
this .catalog = catalog ;
82
+ this .subSchemas = new LoadingCacheLookup <>(new IgnoreCaseLookup <JdbcSchema >() {
83
+ @ Override public @ Nullable JdbcSchema get (String name ) {
84
+ try (Connection connection = dataSource .getConnection ();
85
+ ResultSet resultSet =
86
+ connection .getMetaData ().getSchemas (catalog , name )) {
87
+ while (resultSet .next ()) {
88
+ final String schemaName =
89
+ requireNonNull (resultSet .getString (1 ),
90
+ "got null schemaName from the database" );
91
+ return new JdbcSchema (dataSource , dialect , convention , catalog , schemaName );
92
+ }
93
+ } catch (SQLException e ) {
94
+ throw new RuntimeException (e );
95
+ }
96
+ return null ;
97
+ }
98
+
99
+ @ Override public Set <String > getNames (LikePattern pattern ) {
100
+ final ImmutableSet .Builder <String > builder =
101
+ ImmutableSet .builder ();
102
+ try (Connection connection = dataSource .getConnection ();
103
+ ResultSet resultSet =
104
+ connection .getMetaData ().getSchemas (catalog , pattern .pattern )) {
105
+ while (resultSet .next ()) {
106
+ builder .add (
107
+ requireNonNull (resultSet .getString (1 ),
108
+ "got null schemaName from the database" ));
109
+ }
110
+ } catch (SQLException e ) {
111
+ throw new RuntimeException (e );
112
+ }
113
+ return builder .build ();
114
+ }
115
+ });
76
116
}
77
117
78
118
public static JdbcCatalogSchema create (
@@ -103,34 +143,25 @@ public static JdbcCatalogSchema create(
103
143
return new JdbcCatalogSchema (dataSource , dialect , convention , catalog );
104
144
}
105
145
106
- private SubSchemaMap computeSubSchemaMap () {
107
- final ImmutableMap .Builder <String , Schema > builder =
108
- ImmutableMap .builder ();
109
- @ Nullable String defaultSchemaName ;
110
- try (Connection connection = dataSource .getConnection ();
111
- ResultSet resultSet =
112
- connection .getMetaData ().getSchemas (catalog , null )) {
113
- defaultSchemaName = connection .getSchema ();
114
- while (resultSet .next ()) {
115
- final String schemaName =
116
- requireNonNull (resultSet .getString (1 ),
117
- "got null schemaName from the database" );
118
- builder .put (schemaName ,
119
- new JdbcSchema (dataSource , dialect , convention , catalog , schemaName ));
120
- }
146
+ @ Override public Lookup <Table > tables () {
147
+ return Lookup .empty ();
148
+ }
149
+
150
+ @ Override public Lookup <? extends Schema > subSchemas () {
151
+ return subSchemas ;
152
+ }
153
+
154
+ private @ Nullable String computeDefaultSchemaName () {
155
+ try (Connection connection = dataSource .getConnection ()) {
156
+ return connection .getSchema ();
121
157
} catch (SQLException e ) {
122
158
throw new RuntimeException (e );
123
159
}
124
- return new SubSchemaMap (defaultSchemaName , builder .build ());
125
- }
126
-
127
- @ Override protected Map <String , Schema > getSubSchemaMap () {
128
- return subSchemaMapSupplier .get ().map ;
129
160
}
130
161
131
162
/** Returns the name of the default sub-schema. */
132
163
public @ Nullable String getDefaultSubSchemaName () {
133
- return subSchemaMapSupplier .get ().defaultSchemaName ;
164
+ return defaultSchemaName .get ().orElse ( null ) ;
134
165
}
135
166
136
167
/** Returns the data source. */
@@ -148,16 +179,4 @@ public DataSource getDataSource() {
148
179
}
149
180
return null ;
150
181
}
151
-
152
- /** Contains sub-schemas by name, and the name of the default schema. */
153
- private static class SubSchemaMap {
154
- final @ Nullable String defaultSchemaName ;
155
- final ImmutableMap <String , Schema > map ;
156
-
157
- private SubSchemaMap (@ Nullable String defaultSchemaName ,
158
- ImmutableMap <String , Schema > map ) {
159
- this .defaultSchemaName = defaultSchemaName ;
160
- this .map = map ;
161
- }
162
- }
163
182
}
0 commit comments