001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.core.search.mysql;
034:
035: import com.flexive.core.Database;
036: import com.flexive.core.search.FieldSelector;
037: import com.flexive.core.search.PropertyEntry;
038: import com.flexive.shared.exceptions.FxSqlSearchException;
039: import com.flexive.shared.structure.FxDataType;
040: import com.flexive.shared.FxSharedUtils;
041: import com.flexive.sqlParser.Property;
042: import org.apache.commons.logging.Log;
043: import org.apache.commons.logging.LogFactory;
044: import org.apache.commons.lang.StringUtils;
045:
046: import java.sql.Connection;
047: import java.sql.ResultSet;
048: import java.sql.ResultSetMetaData;
049: import java.sql.Statement;
050: import java.util.Map;
051: import java.util.HashMap;
052:
053: /**
054: * A generic MySQL selector
055: *
056: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
057: * @version $Rev: 256 $
058: */
059: class MySQLGenericSelector implements FieldSelector {
060: private static final Log LOG = LogFactory
061: .getLog(MySQLGenericSelector.class);
062:
063: private final Map<String, FxDataType> columns = new HashMap<String, FxDataType>();
064: private final String tableName;
065: private final String linksOn;
066:
067: protected MySQLGenericSelector(String tableName, String linksOn) {
068: FxSharedUtils.checkParameterNull(tableName, "tableName");
069: FxSharedUtils.checkParameterNull(linksOn, "linksOn");
070: Connection con = null;
071: Statement stmt = null;
072: this .tableName = tableName;
073: this .linksOn = linksOn;
074: try {
075: con = Database.getDbConnection();
076: stmt = con.createStatement();
077: ResultSet rs = stmt.executeQuery("SELECT * FROM "
078: + tableName + " LIMIT 0");
079: ResultSetMetaData md = rs.getMetaData();
080: for (int pos = 1; pos <= md.getColumnCount(); pos++) {
081: String columnName = md.getColumnName(pos);
082: FxDataType columnType;
083: switch (md.getColumnType(pos)) {
084: case java.sql.Types.CHAR:
085: case java.sql.Types.VARCHAR:
086: case java.sql.Types.LONGVARCHAR:
087: columnType = FxDataType.String1024;
088: break;
089: case java.sql.Types.BOOLEAN:
090: columnType = FxDataType.Boolean;
091: break;
092: case java.sql.Types.TINYINT:
093: case java.sql.Types.SMALLINT:
094: case java.sql.Types.INTEGER:
095: case java.sql.Types.BIT:
096: columnType = FxDataType.Number;
097: break;
098: case java.sql.Types.DECIMAL:
099: columnType = FxDataType.Double;
100: break;
101: case java.sql.Types.FLOAT:
102: columnType = FxDataType.Float;
103: break;
104: case java.sql.Types.BIGINT:
105: if (columnName.endsWith("ED_AT")) //MODIFIED_AT, CREATED_AT
106: columnType = FxDataType.DateTime;
107: else
108: columnType = FxDataType.LargeNumber;
109: break;
110: case java.sql.Types.DATE:
111: columnType = FxDataType.Date;
112: break;
113: case java.sql.Types.TIME:
114: case java.sql.Types.TIMESTAMP:
115: columnType = FxDataType.DateTime;
116: break;
117: default:
118: columnType = FxDataType.String1024;
119: }
120: columns.put(columnName, columnType);
121: }
122:
123: } catch (Throwable t) {
124: FxSqlSearchException ex = new FxSqlSearchException(LOG,
125: "ex.sqlSearch.fieldSelector.initializeFailed",
126: tableName, t.getMessage());
127: LOG.error(ex.getMessage(), ex);
128: throw ex.asRuntimeException();
129: } finally {
130: Database
131: .closeObjects(MySQLGenericSelector.class, con, stmt);
132: }
133: }
134:
135: /**
136: * {@inheritDoc}
137: */
138: public void apply(Property prop, PropertyEntry entry,
139: StringBuffer statement) throws FxSqlSearchException {
140: FxDataType type = columns.get(prop.getField());
141: if (type == null) {
142: // This field does not exist
143: throw new FxSqlSearchException(LOG,
144: "ex.sqlSearch.query.undefinedField", prop
145: .getField(), prop.getPropertyName(),
146: getAllowedFields());
147: } else {
148: statement.insert(
149: 0,
150: "(select " + prop.getField() + " from " + tableName
151: + " where " + linksOn + "=").append(")");
152: entry.overrideDataType(type);
153: }
154: }
155:
156: /**
157: * {@inheritDoc}
158: */
159: public String getAllowedFields() {
160: return StringUtils.join(columns.keySet(), ',');
161: }
162: }
|