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.util.ArrayList;
24 import org.glom.libglom.Document;
25 import org.glom.libglom.Field;
26 import org.glom.libglom.FieldVector;
27 import org.glom.libglom.Glom;
28 import org.glom.libglom.LayoutGroupVector;
29 import org.glom.libglom.LayoutItem;
30 import org.glom.libglom.LayoutItemVector;
31 import org.glom.libglom.LayoutItem_Field;
32 import org.glom.libglom.LayoutItem_Portal;
33 import org.glom.libglom.Relationship;
34 import org.glom.libglom.SortClause;
35 import org.glom.web.server.Log;
36 import org.glom.web.shared.DataItem;
38 import com.mchange.v2.c3p0.ComboPooledDataSource;
41 * @author Ben Konrath <ben@bagu.org>
44 public class RelatedListDBAccess extends ListDBAccess {
45 private String foreignKeyValue = null;
46 private LayoutItem_Portal portal = null;
47 private String parentTable = null;
48 private String whereClauseToTableName = null;
49 private Field whereClauseToKeyField = null;
51 public RelatedListDBAccess(Document document, String documentID, ComboPooledDataSource cpds, String tableName,
52 String relationshipName) {
53 super(document, documentID, cpds, tableName);
55 // find the LayoutItem_Portal for the related list name
56 LayoutGroupVector layoutGroupVec = document.get_data_layout_groups("details", tableName);
57 // LayoutItem_Portal portal = null;
58 for (int i = 0; i < layoutGroupVec.size(); i++) {
59 org.glom.libglom.LayoutGroup layoutGroup = layoutGroupVec.get(i);
60 portal = getPortalForRelationship(relationshipName, layoutGroup);
67 Log.error(documentID, tableName, "Couldn't find LayoutItem_Portal \"" + relationshipName + "\" in table \""
68 + tableName + "\". " + "Cannot retrive data for the related list.");
72 parentTable = tableName;
73 // Reassign the tableName variable to table that is being used for the related list. This needs to be set before
74 // getFieldsToShowForSQLQuery().
75 this.tableName = portal.get_table_used("" /* parent table - not relevant */);
77 // Convert the libglom LayoutGroup object into a LayoutFieldVector suitable for SQL queries.
78 LayoutGroupVector tempLayoutGroupVec = new LayoutGroupVector();
79 tempLayoutGroupVec.add(portal);
80 fieldsToGet = getFieldsToShowForSQLQuery(tempLayoutGroupVec);
83 * The code from the rest of this method was ported from Glom: Base_DB::set_found_set_where_clause_for_portal()
85 Relationship relationship = portal.get_relationship();
87 // Notice that, in the case that this is a portal to doubly-related records,
88 // The WHERE clause mentions the first-related table (though by the alias defined in extra_join)
89 // and we add an extra JOIN to mention the second-related table.
91 whereClauseToTableName = relationship.get_to_table();
92 whereClauseToKeyField = getFieldInTable(relationship.get_to_field(), relationship.get_to_table());
94 Relationship relationshipRelated = portal.get_related_relationship();
95 if (relationshipRelated != null) {
96 // FIXME port this Glom code to Java
100 sharedptr<UsesRelationship> uses_rel_temp = sharedptr<UsesRelationship>::create();
101 uses_rel_temp->set_relationship(relationship);
102 found_set.m_extra_join = relationship;
104 //Adjust the WHERE clause appropriately for the extra JOIN:
105 whereClauseToTableName = uses_rel_temp->get_sql_join_alias_name();
107 const Glib::ustring to_field_name = uses_rel_temp->get_to_field_used();
108 where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), to_field_name);
109 std::cout << "extra_join=" << found_set.m_extra_join << std::endl;
110 std::cout << "extra_join where_clause_to_key_field=" << where_clause_to_key_field->get_name() << std::endl;
117 public ArrayList<DataItem[]> getData(int start, int length, String foreignKeyValue, boolean useSortClause,
118 int sortColumnIndex, boolean isAscending) {
120 if (tableName == null || foreignKeyValue == null || foreignKeyValue.isEmpty()) {
124 // Set the foreignKeyValue
125 this.foreignKeyValue = foreignKeyValue;
127 return getListData(start, length, useSortClause, sortColumnIndex, isAscending);
130 private LayoutItem_Portal getPortalForRelationship(String relationshipName, org.glom.libglom.LayoutGroup layoutGroup) {
132 if (relationshipName == null)
135 LayoutItemVector items = layoutGroup.get_items();
136 for (int i = 0; i < items.size(); i++) {
137 LayoutItem layoutItem = items.get(i);
139 LayoutItem_Field layoutItemField = LayoutItem_Field.cast_dynamic(layoutItem);
140 if (layoutItemField != null) {
141 // the layoutItem is a LayoutItem_Field
145 // the layoutItem is not a LayoutItem_Field
146 org.glom.libglom.LayoutGroup subLayoutGroup = org.glom.libglom.LayoutGroup.cast_dynamic(layoutItem);
147 if (subLayoutGroup != null) {
148 // the layoutItem is a LayoutGroup
149 LayoutItem_Portal layoutItemPortal = LayoutItem_Portal.cast_dynamic(layoutItem);
150 if (layoutItemPortal != null) {
151 // The subGroup is a LayoutItem_Protal
152 if (relationshipName.equals(layoutItemPortal.get_relationship_name_used())) {
154 return layoutItemPortal;
157 // The subGroup is not a LayoutItem_Portal.
158 LayoutItem_Portal retval = getPortalForRelationship(relationshipName, subLayoutGroup);
159 if (retval != null) {
167 // the LayoutItem_Portal with relationshipName was not found
174 * @see org.glom.web.server.ListDBAccess#getExpectedResultSize()
176 public int getExpectedResultSize(String foreignKeyValue) {
178 // Set the foreignKeyValue
179 this.foreignKeyValue = foreignKeyValue;
181 if (fieldsToGet == null || fieldsToGet.size() <= 0 || this.foreignKeyValue == null)
184 return getResultSizeOfSQLQuery();
190 * @see org.glom.web.server.ListDBAccess#getSelectQuery(org.glom.libglom.LayoutFieldVector,
191 * org.glom.libglom.SortClause)
194 protected String getSelectQuery(SortClause sortClause) {
196 if (portal == null) {
197 Log.error(documentID, parentTable,
198 "The Portal has not been found. Cannot build query for the related list.");
202 if (foreignKeyValue == null || foreignKeyValue.isEmpty()) {
203 Log.error(documentID, parentTable,
204 "The value for the foreign key has not been set. Cannot build query for the related list.");
208 return Glom.build_sql_select_with_where_clause(tableName, fieldsToGet, whereClauseToTableName,
209 whereClauseToKeyField, foreignKeyValue, null, sortClause);
213 private Field getFieldInTable(String fieldName, String tableName) {
215 if (tableName.isEmpty() || fieldName.isEmpty())
218 FieldVector fields = document.get_table_fields(tableName);
219 for (int i = 0; i < fields.size(); i++) {
220 Field field = fields.get(i);
221 if (fieldName.equals(field.get_name())) {
232 * @see org.glom.web.server.ListDBAccess#getCountQuery()
235 protected String getCountQuery() {
236 if (portal == null) {
237 Log.error(documentID, parentTable,
238 "The Portal has not been found. Cannot build query for the related list.");
242 if (foreignKeyValue == null || foreignKeyValue.isEmpty()) {
243 Log.error(documentID, parentTable,
244 "The value for the foreign key has not been set. Cannot build query for the related list.");
248 return Glom.build_sql_select_count_with_where_clause(tableName, fieldsToGet, whereClauseToTableName,
249 whereClauseToKeyField, foreignKeyValue);