001: package simpleorm.data.dynabeanadaptor;
002:
003: import simpleorm.data.*;
004:
005: import java.util.*;
006:
007: import org.apache.commons.beanutils.*;
008:
009: /**
010: * Test connection, implementing a simple map "database" of DynaBeans.
011: * Lots of cloning to simulate a database like behavior.
012: */
013: public class DDynaConnection extends DConnection {
014:
015: /** key is tablename|pkey */
016: DDynaDatabase records;
017:
018: public DDynaConnection(DDynaDatabase records) {
019: this .records = records;
020: }
021:
022: public @Override
023: DRecordInstance newInstance(DRecordMeta meta) {
024: DynaClass dc = makeDynaClass(meta); // should really cache
025: DynaBean bean = null;
026: try {
027: bean = dc.newInstance();
028: } catch (Exception ex) {
029: throw new DException(ex);
030: }
031: DRecordInstance rec = newRawInstance(meta, bean);
032: return rec;
033: }
034:
035: DynaClass makeDynaClass(DRecordMeta meta) {
036: DynaProperty[] props = new DynaProperty[meta.getFields().size()];
037: int px = 0;
038: for (DFieldMeta field : meta.getFields()) {
039: props[px] = new DynaProperty(field.getName(), field
040: .getType().getClazz());
041: px++;
042: //System.err.println("mdc " + props[px] + field.getName() + " " + field.getType().getClazz().getSimpleName());
043: }
044: //System.err.println(" "+meta.getTableName() + props.length);
045: BasicDynaClass dynaClass = new BasicDynaClass(meta
046: .getTableName(), null, props);
047: return dynaClass;
048: }
049:
050: public void insert(DRecordInstance record) {
051: record.onPreUpSert(this , DRecordInstance.QueryMode.INSERT);
052: String pkey = record.getRecordMeta().getTableName() + "|"
053: + record.hackPrimaryKeyString();
054: DynaBean bean = (DynaBean) getBean(record);
055: records.insert(pkey, bean); // should clone
056: //System.err.println("Inserted " + pkey);
057: }
058:
059: public void update(DRecordInstance record) {
060: record.onPreUpSert(this , DRecordInstance.QueryMode.UPDATE);
061: String pkey = record.getRecordMeta().getTableName() + "|"
062: + record.hackPrimaryKeyString();
063: DynaBean bean = (DynaBean) getBean(record);
064: records.update(pkey, bean); // should clone
065: }
066:
067: // public void delete(DRecordInstance record) {
068: // String pkey = record.hackPrimaryKeyString();
069: // DRecordInstance rec = records.search(pkey);
070: // if ( rec != null )
071: // throw new DException("Duplicate record " + record);
072: //
073: // int rx = findRecord(record);
074: // if ( rx < 0 )
075: // throw new DException("Record not foundrecord " + record);
076: // records.remove(rx);
077: // }
078:
079: public Iterator<DRecordInstance> executeQuery(DQuery query) {
080:
081: /// Optimization if primary key search
082: Iterator<DRecordInstance> pkey = primaryKeyGet(query);
083: if (pkey != null)
084: return pkey;
085:
086: /// Normal case, a linear search (for this connection)
087: ArrayList out = new ArrayList();
088: int recNr = 0;
089: for (DynaBean bean : records.values()) {
090: // todo bean type
091: DRecordInstance rec = newRawInstance(query.getRecordMeta(),
092: bean); // Should clone, which is Grossly inefficient
093: if (query.match(rec)) {
094: if (++recNr > query.getOffset())
095: out.add(rec);
096: if (recNr >= query.getOffset() + query.getLimit())
097: break;
098: }
099: }
100: Collections.sort(out, query);
101: return out.iterator();
102: }
103:
104: private Iterator<DRecordInstance> primaryKeyGet(DQuery query) {
105: String pkey = query.getRecordMeta().getTableName() + "|";
106: for (DFieldMeta field : query.getRecordMeta().getFields()) {
107: if (field.isPrimaryKey()) {
108: DQuery.Criteria crit = null;
109: for (DQuery.Criteria cr : query.getCriteriaFields()) {
110: if (cr.getEqField() == field) {
111: crit = cr;
112: break;
113: }
114: }
115: if (crit == null)
116: return null; // primary key not covered in query
117: pkey += crit.getEqValue() + "~";
118: }
119: }
120: DynaBean bean = records.search(pkey);
121: ArrayList resultSet = new ArrayList(1);
122: if (bean != null) {
123: DRecordInstance rec = newRawInstance(query.getRecordMeta(),
124: bean); // should clone
125: resultSet.add(rec);
126: }
127: return (Iterator<DRecordInstance>) resultSet.iterator();
128: }
129:
130: public boolean canLockRecords() {
131: return false;
132: }
133:
134: }
|