001: /**
002: * Copyright (C) 2006 NetMind Consulting Bt.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 3 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package hu.netmind.persistence.parser;
018:
019: import hu.netmind.persistence.DateSerialUtil;
020: import java.util.Date;
021: import java.util.Map;
022: import java.util.HashMap;
023: import org.apache.log4j.Logger;
024:
025: /**
026: * Keeps an exact moment in time for the query to run.
027: * @author Brautigam Robert
028: * @version Revision: $Revision$
029: */
030: public class TimeControl {
031: private static Logger logger = Logger.getLogger(TimeControl.class);
032:
033: private Long serial;
034: private Long txSerial;
035: private boolean applyTransaction = false;
036:
037: public TimeControl(TimeControl timeControl) {
038: this .serial = timeControl.serial;
039: this .txSerial = timeControl.txSerial;
040: this .applyTransaction = timeControl.applyTransaction;
041: }
042:
043: public TimeControl(Long serial, Long txSerial,
044: boolean applyTransaction) {
045: this .serial = serial;
046: this .txSerial = txSerial;
047: this .applyTransaction = applyTransaction;
048: }
049:
050: public boolean isApplyTransaction() {
051: return applyTransaction;
052: }
053:
054: public void setApplyTransaction(boolean applyTransaction) {
055: this .applyTransaction = applyTransaction;
056: }
057:
058: public Long getSerial() {
059: return serial;
060: }
061:
062: public void setSerial(Long serial) {
063: this .serial = serial;
064: }
065:
066: public Long getTxSerial() {
067: return txSerial;
068: }
069:
070: public void setTxSerial(Long txSerial) {
071: this .txSerial = txSerial;
072: }
073:
074: public void setQueryDate(Date date) {
075: serial = new Long(DateSerialUtil.getSerial(date));
076: if ((txSerial != null)
077: && (serial.longValue() < txSerial.longValue())) {
078: // Serial is before the tx's first modification took place,
079: // so transaction conditions are not necessary
080: setApplyTransaction(false);
081: }
082: }
083:
084: /**
085: * Apply this time control to a table which is a left term,
086: * so possibly it is not available.
087: */
088: public void applyToLeftTable(Expression expression, TableTerm term) {
089: // This is a left table term, so persistence_start and
090: // persistence_end can also be null. If this is true,
091: // then persistence_id is null too, so check that.
092: // (if there is no row for the left join)
093: Expression subExpr = new Expression();
094: subExpr.setLeftTableTerm(term);
095: subExpr.add(new ReferenceTerm(term, "persistence_id"));
096: subExpr.add("is null");
097: subExpr.add("or");
098: Expression subExpr2 = new Expression();
099: subExpr.add(subExpr2);
100: // Apply to subExpr2
101: apply(subExpr2, term);
102: // Add to expression
103: expression.add(subExpr);
104: }
105:
106: /**
107: * Apply this time control to the table given.
108: */
109: public void apply(Expression expression, TableTerm term) {
110: Expression timeExpr = new Expression();
111: Long safeSerial = txSerial;
112: if ((safeSerial == null)
113: || (safeSerial.longValue() > serial.longValue()))
114: safeSerial = serial;
115: if (logger.isDebugEnabled())
116: logger.debug("applying time control to: " + term
117: + ", safe serial: " + safeSerial + ", txSerial: "
118: + txSerial);
119: // Apply the constraints, first the start serial.
120: Expression partExpr = new Expression();
121: if (applyTransaction) {
122: // If entry is inside the transaction, then we allow entries
123: // inside the serial boundary.
124: partExpr.add(new ReferenceTerm(term,
125: "persistence_txstartid"));
126: partExpr.add("=");
127: partExpr.add(new ConstantTerm(txSerial));
128: partExpr.add("and");
129: partExpr
130: .add(new ReferenceTerm(term, "persistence_txstart"));
131: partExpr.add("<=");
132: partExpr.add(new ConstantTerm(serial));
133: partExpr.add("or");
134: }
135: partExpr.add(new ReferenceTerm(term, "persistence_start"));
136: partExpr.add("<=");
137: partExpr.add(new ConstantTerm(safeSerial));
138: timeExpr.add(partExpr);
139: timeExpr.add("and");
140: // Now add end constraints. This is a little different, because
141: // the end serials need to be enforced.
142: partExpr = new Expression();
143: partExpr.add(new ReferenceTerm(term, "persistence_end"));
144: partExpr.add(">");
145: partExpr.add(new ConstantTerm(safeSerial));
146: if (applyTransaction) {
147: // If entry is in current transaction, then the constraints
148: // are stricter. Disallow entries with endid lower then serial.
149: partExpr.add("and");
150: Expression subExpr = new Expression();
151: subExpr.add(new ReferenceTerm(term, "persistence_txendid"));
152: subExpr.add("<>");
153: subExpr.add(new ConstantTerm(txSerial));
154: subExpr.add("or");
155: subExpr.add(new ReferenceTerm(term, "persistence_txend"));
156: subExpr.add(">");
157: subExpr.add(new ConstantTerm(serial));
158: partExpr.add(subExpr);
159: }
160: timeExpr.add(partExpr);
161: // Add all constraints
162: expression.addAll(timeExpr);
163: }
164:
165: public String toString() {
166: return "[" + serial + "," + txSerial + "," + applyTransaction
167: + "]";
168: }
169: }
|