1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 package com.sun.star.sdbcx.comp.postgresql;
23 
24 import java.util.List;
25 
26 import com.sun.star.beans.UnknownPropertyException;
27 import com.sun.star.beans.XPropertySet;
28 import com.sun.star.container.ElementExistException;
29 import com.sun.star.lang.IllegalArgumentException;
30 import com.sun.star.lang.WrappedTargetException;
31 import com.sun.star.sdbc.SQLException;
32 import com.sun.star.sdbc.XDatabaseMetaData;
33 import com.sun.star.sdbc.XResultSet;
34 import com.sun.star.sdbc.XRow;
35 import com.sun.star.sdbc.XStatement;
36 import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
37 import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
38 import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxTableDescriptor;
39 import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
40 import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
41 import com.sun.star.sdbcx.comp.postgresql.util.DbTools.NameComponents;
42 import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
43 import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
44 import com.sun.star.uno.Any;
45 import com.sun.star.uno.AnyConverter;
46 import com.sun.star.uno.UnoRuntime;
47 
48 public class PostgresqlTables extends OContainer {
49     private XDatabaseMetaData metadata;
50     private PostgresqlCatalog catalog;
51 
52     public PostgresqlTables(Object lock, XDatabaseMetaData metadata, PostgresqlCatalog catalog, List<String> names) throws ElementExistException {
53         super(lock, true, names);
54         this.metadata = metadata;
55         this.catalog = catalog;
56     }
57 
58     @Override
59     public XPropertySet createObject(String name) throws SQLException {
60         NameComponents nameComponents = DbTools.qualifiedNameComponents(metadata, name, ComposeRule.InDataManipulation);
61         Object queryCatalog = nameComponents.getCatalog().isEmpty() ? Any.VOID : nameComponents.getCatalog();
62         XPropertySet ret = null;
63         XResultSet results = null;
64         try {
65             results = metadata.getTables(
66                     queryCatalog, nameComponents.getSchema(), nameComponents.getTable(), new String[] { "VIEW", "TABLE", "%" });
67             if (results != null) {
68                 XRow row = UnoRuntime.queryInterface(XRow.class, results);
69                 if (results.next()) {
70                     String type = row.getString(4);
71                     String remarks = row.getString(5);
72                     ret = new PostgresqlTable(metadata.getConnection(), this, nameComponents.getTable(),
73                             nameComponents.getCatalog(), nameComponents.getSchema(), remarks, type);
74                 }
75             }
76         } finally {
77             CompHelper.disposeComponent(results);
78         }
79         return ret;
80 
81     }
82 
83     @Override
84     public void dropObject(int index, String name) throws SQLException {
85         try {
86             Object object = getObject(index);
87 
88             NameComponents nameComponents = DbTools.qualifiedNameComponents(metadata, name, ComposeRule.InDataManipulation);
89 
90             boolean isView = false;
91             XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, object);
92             if (propertySet != null) {
93                 isView = AnyConverter.toString(propertySet.getPropertyValue(PropertyIds.TYPE.name)).equals("VIEW");
94             }
95 
96             String composedName = DbTools.composeTableName(metadata, nameComponents.getCatalog(), nameComponents.getSchema(), nameComponents.getTable(),
97                     true, ComposeRule.InDataManipulation);
98             String sql = String.format("DROP %s %s", isView ? "VIEW" : "TABLE", composedName);
99 
100             XStatement statement = null;
101             try {
102                 statement = metadata.getConnection().createStatement();
103                 statement.execute(sql);
104             } finally {
105                 CompHelper.disposeComponent(statement);
106             }
107             // FIXME: delete it from our views
108         } catch (IllegalArgumentException | UnknownPropertyException | WrappedTargetException wrappedTargetException) {
109             throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, wrappedTargetException);
110         }
111     }
112 
113     @Override
114     public void impl_refresh() {
115         catalog.refreshObjects();
116     }
117 
118     @Override
119     public XPropertySet createDescriptor() {
120         return new SdbcxTableDescriptor(true);
121     }
122 
123     @Override
124     public XPropertySet appendObject(String name, XPropertySet descriptor) throws SQLException {
125         createTable(descriptor);
126         return createObject(name);
127     }
128 
129     void createTable(XPropertySet descriptor) throws SQLException {
130         XStatement statement = null;
131         try {
132             String sql = DbTools.createSqlCreateTableStatement(descriptor, metadata.getConnection(), null, "(M,D)");
133             statement = metadata.getConnection().createStatement();
134             statement.execute(sql);
135         } finally {
136             CompHelper.disposeComponent(statement);
137         }
138     }
139 }
140