2 * Copyright (C) 2011 Openismus GmbH
4 * This file is part of GWT-Glom.
6 * GWT-Glom is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
11 * GWT-Glom is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with GWT-Glom. If not, see <http://www.gnu.org/licenses/>.
20 package org.glom.web.server.database;
22 import java.sql.ResultSet;
23 import java.sql.ResultSetMetaData;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.List;
28 import org.glom.web.server.Log;
29 import org.glom.web.server.SqlUtils;
30 import org.glom.web.server.Utils;
31 import org.glom.web.server.libglom.Document;
32 import org.glom.web.shared.DataItem;
33 import org.glom.web.shared.TypedDataItem;
34 import org.glom.web.shared.libglom.Field;
35 import org.glom.web.shared.libglom.layout.LayoutGroup;
36 import org.glom.web.shared.libglom.layout.LayoutItem;
37 import org.glom.web.shared.libglom.layout.LayoutItemField;
38 import org.glom.web.shared.libglom.layout.LayoutItemPortal;
40 import com.mchange.v2.c3p0.ComboPooledDataSource;
45 public abstract class DBAccess {
46 public Document document;
47 protected String documentID;
48 protected String tableName;
49 protected ComboPooledDataSource cpds;
51 protected DBAccess(final Document document, final String documentID, final ComboPooledDataSource cpds,
52 final String tableName) {
53 this.document = document;
54 this.documentID = documentID;
56 this.tableName = tableName;
60 * Converts data from a ResultSet to an ArrayList of DataItem array suitable for sending back to the client.
62 final protected ArrayList<DataItem[]> convertResultSetToDTO(final int length,
63 final List<LayoutItemField> layoutFields, final TypedDataItem primaryKeyValue, final ResultSet rs) throws SQLException {
65 final ResultSetMetaData rsMetaData = rs.getMetaData();
66 final int rsColumnscount = rsMetaData.getColumnCount();
68 // get the data we've been asked for
70 final ArrayList<DataItem[]> rowsList = new ArrayList<DataItem[]>();
71 while (rs.next() && rowCount <= length) {
72 final int layoutFieldsSize = Utils.safeLongToInt(layoutFields.size());
73 final DataItem[] rowArray = new DataItem[layoutFieldsSize];
74 for (int i = 0; i < layoutFieldsSize; i++) {
75 // make a new DataItem to set the text and colors
76 final DataItem dataItem = new DataItem();
78 final LayoutItemField field = layoutFields.get(i);
80 if (i >= rsColumnscount) {
81 Log.error("convertResultSetToDTO(): index i=" + i + "+1 (field=" + field.getName()
82 + " is out of range for the ResultSet. Using empty string for value.");
87 final int rsIndex = i + 1; // Because java.sql.ResultSet is 1-indexed, for some reason.
89 // Convert the field value to a string based on the glom type. We're doing the formatting on the
90 // server side for now but it might be useful to move this to the client side.
91 SqlUtils.fillDataItemFromResultSet(dataItem, field, rsIndex, rs, documentID, tableName, primaryKeyValue);
93 rowArray[i] = dataItem;
96 // add the row of DataItems to the ArrayList we're going to return and update the row count
97 rowsList.add(rowArray);
105 * Gets a list to use when generating an SQL query.
107 protected List<LayoutItemField> getFieldsToShowForSQLQuery(final List<LayoutGroup> layoutGroupVec) {
108 final List<LayoutItemField> listLayoutFIelds = new ArrayList<LayoutItemField>();
110 // We will show the fields that the document says we should:
111 for (int i = 0; i < layoutGroupVec.size(); i++) {
112 final LayoutGroup layoutGroup = layoutGroupVec.get(i);
114 // satisfy the precondition of getDetailsLayoutGroup(String tableName, LayoutGroup
115 // libglomLayoutGroup)
116 if (layoutGroup == null) {
121 final ArrayList<LayoutItemField> layoutItemFields = getFieldsToShowForSQLQueryAddGroup(layoutGroup);
122 for (final LayoutItemField layoutItem_Field : layoutItemFields) {
123 listLayoutFIelds.add(layoutItem_Field);
126 return listLayoutFIelds;
130 * Gets an ArrayList of LayoutItem_Field objects to use when generating an SQL query.
132 * @precondition libglomLayoutGroup must not be null
134 private ArrayList<LayoutItemField> getFieldsToShowForSQLQueryAddGroup(final LayoutGroup libglomLayoutGroup) {
136 final ArrayList<LayoutItemField> layoutItemFields = new ArrayList<LayoutItemField>();
137 final List<LayoutItem> items = libglomLayoutGroup.getItems();
138 final int numItems = Utils.safeLongToInt(items.size());
139 for (int i = 0; i < numItems; i++) {
140 final LayoutItem layoutItem = items.get(i);
142 if (layoutItem instanceof LayoutItemField) {
143 final LayoutItemField layoutItemField = (LayoutItemField) layoutItem;
144 // the layoutItem is a LayoutItem_Field
146 // Make sure that it has full field details:
147 // TODO: Is this necessary?
148 String tableNameToUse = tableName;
149 if (layoutItemField.getHasRelationshipName()) {
150 tableNameToUse = layoutItemField.getTableUsed(tableName);
153 final Field field = document.getField(tableNameToUse, layoutItemField.getName());
155 layoutItemField.setFullFieldDetails(field);
157 Log.warn(document.getDatabaseTitleOriginal(), tableName,
158 "LayoutItem_Field " + layoutItemField.getLayoutDisplayName()
159 + " not found in document field list.");
162 // Add it to the list:
163 layoutItemFields.add(layoutItemField);
164 } else if (layoutItem instanceof LayoutGroup) {
165 final LayoutGroup subLayoutGroup = (LayoutGroup) layoutItem;
167 if (!(subLayoutGroup instanceof LayoutItemPortal)) {
168 // The subGroup is not a LayoutItemPortal.
169 // We're ignoring portals because they are filled by means of a separate SQL query.
170 layoutItemFields.addAll(getFieldsToShowForSQLQueryAddGroup(subLayoutGroup));
174 return layoutItemFields;
178 * Gets the primary key LayoutItem_Field for the specified table.
181 * name of table to search for the primary key LayoutItem_Field
182 * @return primary key LayoutItem_Field
184 protected LayoutItemField getPrimaryKeyLayoutItemField(final String tableName) {
185 final Field primaryKey = document.getTablePrimaryKeyField(tableName);
187 final LayoutItemField libglomLayoutItemField = new LayoutItemField();
189 if (primaryKey != null) {
190 libglomLayoutItemField.setName(primaryKey.getName());
191 libglomLayoutItemField.setFullFieldDetails(primaryKey);
193 Log.error(document.getDatabaseTitleOriginal(), this.tableName,
194 "A primary key was not found in the FieldVector for this table.");
197 return libglomLayoutItemField;