View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.data.pipeline.postgresql.ddlgenerator;
19  
20  import java.sql.Connection;
21  import java.sql.SQLException;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.LinkedHashMap;
25  import java.util.Map;
26  
27  /**
28   * Table properties loader for PostgreSQL.
29   */
30  public final class PostgreSQLTablePropertiesLoader extends AbstractPostgreSQLDDLAdapter {
31      
32      private final String tableName;
33      
34      private final String schemaName;
35      
36      public PostgreSQLTablePropertiesLoader(final Connection connection, final String tableName, final String schemaName, final int majorVersion, final int minorVersion) {
37          super(connection, majorVersion, minorVersion);
38          this.tableName = tableName;
39          this.schemaName = schemaName;
40      }
41      
42      /**
43       * Load table properties.
44       *
45       * @return loaded table properties
46       * @throws SQLException SQL exception
47       */
48      public Map<String, Object> load() throws SQLException {
49          Map<String, Object> result = new LinkedHashMap<>();
50          fetchDataBaseId(result);
51          fetchSchemaId(result);
52          fetchTableId(result);
53          fetchTableProperties(result);
54          return result;
55      }
56      
57      private void fetchDataBaseId(final Map<String, Object> context) throws SQLException {
58          Map<String, Object> params = new LinkedHashMap<>();
59          params.put("databaseName", getConnection().getCatalog());
60          context.putAll(executeByTemplateForSingleRow(params, "component/table/%s/get_database_id.ftl"));
61      }
62      
63      private void fetchTableId(final Map<String, Object> context) {
64          Map<String, Object> params = new LinkedHashMap<>();
65          params.put("schemaName", schemaName);
66          params.put("tableName", tableName);
67          context.putAll(executeByTemplateForSingleRow(params, "component/table/%s/get_table_id.ftl"));
68      }
69      
70      private void fetchSchemaId(final Map<String, Object> context) {
71          Map<String, Object> params = new LinkedHashMap<>();
72          params.put("schemaName", schemaName);
73          context.putAll(executeByTemplateForSingleRow(params, "component/table/%s/get_schema_id.ftl"));
74      }
75      
76      private void fetchTableProperties(final Map<String, Object> context) throws SQLException {
77          context.putAll(executeByTemplateForSingleRow(context, "component/table/%s/properties.ftl"));
78          updateAutovacuumProperties(context);
79          checkRlspolicySupport(context);
80          formatSecurityLabels(context);
81      }
82      
83      private void updateAutovacuumProperties(final Map<String, Object> context) {
84          if (null == context.get("autovacuum_enabled")) {
85              context.put("autovacuum_enabled", "x");
86          } else if (Boolean.TRUE.toString().equalsIgnoreCase(context.get("autovacuum_enabled").toString())) {
87              context.put("autovacuum_enabled", "t");
88          } else {
89              context.put("autovacuum_enabled", "f");
90          }
91          if (null == context.get("toast_autovacuum_enabled")) {
92              context.put("toast_autovacuum_enabled", "x");
93          } else if (Boolean.TRUE.toString().equalsIgnoreCase(context.get("toast_autovacuum_enabled").toString())) {
94              context.put("toast_autovacuum_enabled", "t");
95          } else {
96              context.put("toast_autovacuum_enabled", "f");
97          }
98          context.put("autovacuum_custom", anyIsTrue(Arrays.asList(
99                  context.get("autovacuum_vacuum_threshold"),
100                 context.get("autovacuum_vacuum_scale_factor"),
101                 context.get("autovacuum_analyze_threshold"),
102                 context.get("autovacuum_analyze_scale_factor"),
103                 context.get("autovacuum_vacuum_cost_delay"),
104                 context.get("autovacuum_vacuum_cost_limit"),
105                 context.get("autovacuum_freeze_min_age"),
106                 context.get("autovacuum_freeze_max_age"),
107                 context.get("autovacuum_freeze_table_age"))) || "t".equals(context.get("autovacuum_enabled")) || "f".equals(context.get("autovacuum_enabled")));
108         context.put("toast_autovacuum", anyIsTrue(Arrays.asList(
109                 context.get("toast_autovacuum_vacuum_threshold"),
110                 context.get("toast_autovacuum_vacuum_scale_factor"),
111                 context.get("toast_autovacuum_analyze_threshold"),
112                 context.get("toast_autovacuum_analyze_scale_factor"),
113                 context.get("toast_autovacuum_vacuum_cost_delay"),
114                 context.get("toast_autovacuum_vacuum_cost_limit"),
115                 context.get("toast_autovacuum_freeze_min_age"),
116                 context.get("toast_autovacuum_freeze_max_age"),
117                 context.get("toast_autovacuum_freeze_table_age"))) || "t".equals(context.get("toast_autovacuum_enabled")) || "f".equals(context.get("toast_autovacuum_enabled")));
118     }
119     
120     private void checkRlspolicySupport(final Map<String, Object> context) {
121         if (context.containsKey("rlspolicy")) {
122             if (context.get("rlspolicy") instanceof String && Boolean.TRUE.toString().equals(context.get("rlspolicy"))) {
123                 context.put("rlspolicy", true);
124             }
125             if (context.get("forcerlspolicy") instanceof String && Boolean.TRUE.toString().equals(context.get("forcerlspolicy"))) {
126                 context.put("forcerlspolicy", true);
127             }
128         }
129     }
130     
131     private boolean anyIsTrue(final Collection<Object> collection) {
132         for (Object each : collection) {
133             if (each instanceof Boolean && (Boolean) each) {
134                 return true;
135             }
136         }
137         return false;
138     }
139 }