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 package com.sun.star.sdbcx.comp.postgresql;
22 
23 import java.util.List;
24 
25 import com.sun.star.beans.UnknownPropertyException;
26 import com.sun.star.beans.XPropertySet;
27 import com.sun.star.container.ElementExistException;
28 import com.sun.star.lang.WrappedTargetException;
29 import com.sun.star.sdbc.SQLException;
30 import com.sun.star.sdbc.XDatabaseMetaData;
31 import com.sun.star.sdbc.XParameters;
32 import com.sun.star.sdbc.XPreparedStatement;
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.CheckOption;
37 import com.sun.star.sdbcx.comp.postgresql.comphelper.CompHelper;
38 import com.sun.star.sdbcx.comp.postgresql.sdbcx.OContainer;
39 import com.sun.star.sdbcx.comp.postgresql.sdbcx.OView;
40 import com.sun.star.sdbcx.comp.postgresql.sdbcx.descriptors.SdbcxViewDescriptor;
41 import com.sun.star.sdbcx.comp.postgresql.util.ComposeRule;
42 import com.sun.star.sdbcx.comp.postgresql.util.DbTools;
43 import com.sun.star.sdbcx.comp.postgresql.util.DbTools.NameComponents;
44 import com.sun.star.sdbcx.comp.postgresql.util.Osl;
45 import com.sun.star.sdbcx.comp.postgresql.util.PropertyIds;
46 import com.sun.star.sdbcx.comp.postgresql.util.StandardSQLState;
47 import com.sun.star.uno.UnoRuntime;
48 
49 public class PostgresqlViews extends OContainer {
50     private PostgresqlCatalog catalog;
51     private XDatabaseMetaData metadata;
52 
53     public PostgresqlViews(Object lock, XDatabaseMetaData metadata, PostgresqlCatalog catalog, List<String> names) throws ElementExistException {
54         super(lock, true, names);
55         this.metadata = metadata;
56         this.catalog = catalog;
57     }
58 
59     @Override
60     protected XPropertySet createObject(String name) throws SQLException {
61         NameComponents nameComponents = DbTools.qualifiedNameComponents(metadata, name, ComposeRule.InDataManipulation);
62 
63         String sql = "SELECT view_definition,check_option FROM INFORMATION_SCHEMA.views WHERE ";
64         if (!nameComponents.getCatalog().isEmpty()) {
65             sql += "table_catalog=? AND ";
66         }
67         if (!nameComponents.getSchema().isEmpty()) {
68             sql += "table_schema=? AND ";
69         }
70         sql += "table_name=?";
71 
72         final String command;
73         final String checkOption;
74         XPreparedStatement statement = null;
75         XResultSet results = null;
76         try {
77             statement = metadata.getConnection().prepareStatement(sql);
78             XParameters parameters = UnoRuntime.queryInterface(XParameters.class, statement);
79             int next = 1;
80             if (!nameComponents.getCatalog().isEmpty()) {
81                 parameters.setString(next++, nameComponents.getCatalog());
82             }
83             if (!nameComponents.getSchema().isEmpty()) {
84                 parameters.setString(next++, nameComponents.getSchema());
85             }
86             parameters.setString(next, nameComponents.getTable());
87             results = statement.executeQuery();
88             if (results.next()) {
89                 XRow row = UnoRuntime.queryInterface(XRow.class, results);
90                 command = row.getString(1);
91                 checkOption = row.getString(2);
92             } else {
93                 throw new SQLException("View not found", this, StandardSQLState.SQL_TABLE_OR_VIEW_NOT_FOUND.text(), 0, null);
94             }
95         } finally {
96             CompHelper.disposeComponent(results);
97             CompHelper.disposeComponent(statement);
98         }
99 
100         final int checkOptionInt;
101         if (checkOption.equals("NONE")) {
102             checkOptionInt = CheckOption.NONE;
103         } else if (checkOption.equals("LOCAL")) {
104             checkOptionInt = CheckOption.LOCAL;
105         } else if (checkOption.equals("CASCADED")) {
106             checkOptionInt = CheckOption.CASCADE;
107         } else {
108             throw new SQLException("Unsupported check option '" + checkOption + "'", this,
109                     StandardSQLState.SQL_FEATURE_NOT_IMPLEMENTED.text(), 0, null);
110         }
111 
112         return new OView(nameComponents.getCatalog(), nameComponents.getSchema(), nameComponents.getTable(), isCaseSensitive(),
113                 command, checkOptionInt);
114     }
115 
116     @Override
117     protected void dropObject(int index, String name) throws SQLException {
118         XStatement statement = null;
119         try {
120             Object object = getObject(index);
121             XPropertySet propertySet = UnoRuntime.queryInterface(XPropertySet.class, object);
122             Osl.ensure(propertySet != null, "Object returned from view collection isn't an XPropertySet");
123             String sql = String.format("DROP VIEW %s", DbTools.composeTableName(metadata, propertySet, ComposeRule.InTableDefinitions,
124                     false, false, true));
125 
126             statement = metadata.getConnection().createStatement();
127             statement.execute(sql);
128         } catch (WrappedTargetException exception) {
129             throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
130         } finally {
131             CompHelper.disposeComponent(statement);
132         }
133     }
134 
135     @Override
136     protected XPropertySet createDescriptor() {
137         return new SdbcxViewDescriptor(isCaseSensitive());
138     }
139 
140     @Override
141     protected XPropertySet appendObject(String _rForName, XPropertySet descriptor) throws SQLException {
142         XStatement statement = null;
143         try {
144             String sql = String.format("CREATE VIEW %s AS %s",
145                     DbTools.composeTableName(metadata, descriptor, ComposeRule.InTableDefinitions, false, false, true),
146                     descriptor.getPropertyValue(PropertyIds.COMMAND.name));
147             statement = metadata.getConnection().createStatement();
148             statement.execute(sql);
149         } catch (WrappedTargetException | UnknownPropertyException exception) {
150             throw new SQLException("Error", this, StandardSQLState.SQL_GENERAL_ERROR.text(), 0, exception);
151         } finally {
152             CompHelper.disposeComponent(statement);
153         }
154         // Append it to the tables container too:
155         catalog.getTablesInternal().insertElement(_rForName, null);
156         return createObject(_rForName);
157     }
158 
159     @Override
160     protected void impl_refresh() {
161         catalog.refreshObjects();
162     }
163 }
164