001: package simpleorm.data.test;
002:
003: import simpleorm.data.*;
004:
005: import java.util.*;
006:
007: /**
008: * Test connection, implementing a trivial collection database of MyRecords (only).
009: * This technique would only be used by an application implementing the interface --
010: * if all that is required is to put them in a hash map then use the DDynaConnection which
011: * automatically creates a DynaBean.<p>
012: *
013: * Lots of cloning to simulate a database like behavior.<p>
014: *
015: * This code is a little messy, but it is an order of magnitude easier than having to write some sort of database!<p>
016: */
017: public class MyConnection extends DConnection {
018:
019: public static class MyBean implements Cloneable {
020: int ID;
021: String NAME;
022: String DESCRIPTION;
023: //byte[] KEY;
024: Object UNQUERIED;
025:
026: public MyBean cloneMyRecord() { // shallow copy
027: try {
028: return (MyBean) clone();
029: } catch (Exception ex) {
030: throw new DException(ex);
031: }
032: }
033:
034: public int getID() {
035: return ID;
036: }
037:
038: public void setID(int ID) {
039: this .ID = ID;
040: }
041:
042: public String getNAME() {
043: return NAME;
044: }
045:
046: public void setNAME(String NAME) {
047: this .NAME = NAME;
048: }
049:
050: public String getDESCRIPTION() {
051: return DESCRIPTION;
052: }
053:
054: public void setDESCRIPTION(String DESCRIPTION) {
055: this .DESCRIPTION = DESCRIPTION;
056: }
057:
058: public Object getUNQUERIED() {
059: return UNQUERIED;
060: }
061:
062: public void setUNQUERIED(Object UNQUERIED) {
063: this .UNQUERIED = UNQUERIED;
064: }
065: }
066:
067: LinkedHashMap<String, MyBean> records = new LinkedHashMap(10);
068:
069: public MyConnection() {
070: }
071:
072: public @Override
073: DRecordInstance newInstance(DRecordMeta meta) {
074: if (!"MY_RECORD".equals(meta.getTableName()))
075: throw new DException(
076: "Only MY_RECORD is supported by this adaptor");
077: Object bean = new MyBean();
078: DRecordInstance rec = newRawInstance(meta, bean);
079: return rec;
080: }
081:
082: public void insert(DRecordInstance record) {
083: if (!"MY_RECORD".equals(record.getRecordMeta().getTableName()))
084: throw new DException(
085: "Only MY_RECORD is supported by this adaptor");
086: record.onPreUpSert(this , DRecordInstance.QueryMode.INSERT);
087: String pkey = record.hackPrimaryKeyString();
088: if (records.get(pkey) != null)
089: throw new DException("Duplicate record " + record);
090: MyBean rec = (MyBean) getBean(record);
091: records.put(pkey, rec.cloneMyRecord()); // shallow copy.
092: //System.err.println("Inserted " + pkey);
093: }
094:
095: public void update(DRecordInstance record) {
096: record.onPreUpSert(this , DRecordInstance.QueryMode.UPDATE);
097: String pkey = record.hackPrimaryKeyString();
098: if (records.get(pkey) == null)
099: throw new DException("Record not foundrecord " + record);
100: MyBean rec = (MyBean) getBean(record);
101: records.put(pkey, rec.cloneMyRecord()); // shallow copy.
102: }
103:
104: // public void delete(DRecordInstance record) {
105: // String pkey = record.hackPrimaryKeyString();
106: // DRecordInstance rec = records.get(pkey);
107: // if ( rec != null )
108: // throw new DException("Duplicate record " + record);
109: //
110: // int rx = findRecord(record);
111: // if ( rx < 0 )
112: // throw new DException("Record not foundrecord " + record);
113: // records.remove(rx);
114: // }
115:
116: public Iterator<DRecordInstance> executeQuery(DQuery query) {
117: if (!"MY_RECORD".equals(query.getRecordMeta().getTableName()))
118: throw new DException(
119: "Only MY_RECORD is supported by this adaptor");
120:
121: /// Optimization if primary key search
122: Iterator<DRecordInstance> pkey = primaryKeyGet(query);
123: if (pkey != null)
124: return pkey;
125:
126: /// Normal case, a linear search (for this connection)
127: ArrayList out = new ArrayList();
128: int recNr = 0;
129: for (MyBean bean : records.values()) {
130: DRecordInstance rec = newRawInstance(query.getRecordMeta(),
131: bean.cloneMyRecord()); // ## Grossly inefficient
132: if (query.match(rec)) {
133: if (++recNr > query.getOffset())
134: out.add(rec);
135: if (recNr >= query.getOffset() + query.getLimit())
136: break;
137: }
138: }
139: Collections.sort(out, query);
140: return out.iterator();
141: }
142:
143: private Iterator<DRecordInstance> primaryKeyGet(DQuery query) {
144: String pkey = "";
145: for (DFieldMeta field : query.getRecordMeta().getFields()) {
146: if (field.isPrimaryKey()) {
147: DQuery.Criteria crit = null;
148: for (DQuery.Criteria cr : query.getCriteriaFields()) {
149: if (cr.getEqField() == field) {
150: crit = cr;
151: break;
152: }
153: }
154: if (crit == null)
155: return null; // primary key not covered in query
156: pkey += crit.getEqValue() + "~";
157: }
158: }
159: MyBean bean = records.get(pkey);
160: ArrayList resultSet = new ArrayList(1);
161: if (bean != null) {
162: DRecordInstance rec = newRawInstance(query.getRecordMeta(),
163: bean.cloneMyRecord());
164: resultSet.add(rec);
165: }
166: return (Iterator<DRecordInstance>) resultSet.iterator();
167: }
168:
169: public boolean canLockRecords() {
170: return false;
171: }
172:
173: }
|