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