001: package simpleorm.data;
002:
003: import java.util.*;
004:
005: /**
006: * Contains the list of field meta data within a record.
007: * (This meta data could just be stored with each instance.
008: * However we need separate meta data objects so that we can
009: * issue queries etc. Also so that we can display a list of instances etc.
010: * But it does )
011: */
012: public class DRecordMeta {
013: Class clazz; // of the DRecordInstance
014: String tableName;
015: Map<String, DFieldMeta> fields = Collections
016: .synchronizedMap(new LinkedHashMap(16));
017: List<DForeignKeyMeta> refingFKeys = new ArrayList(5);
018: List<DForeignKeyMeta> refedFKeys = new ArrayList(5);
019:
020: Object recordImplementation; // eg. ddl utils Table
021:
022: public DRecordMeta(Class clazz, String name) {
023: this .clazz = clazz;
024: this .tableName = name;
025: }
026:
027: public DFieldMeta addField(DFieldMeta field) {
028: if (field.recordMeta != null)
029: throw new DException("DFieldMeta " + field
030: + " already in record " + field.recordMeta);
031: field.recordMeta = this ;
032: fields.put(field.name, field);
033: return field;
034: }
035:
036: /** Adds Foreign key to both the refing (field.record) and refed (this) DRecordMetas.
037: * Ie. generates
038: * CREATE TABLE field.table(...) FOREIGN KEY (field) references this.
039: * (obviously all field.record must be the same.)
040: */
041: public DForeignKeyMeta addRefingFKey(DFieldMeta... fields) {
042: DForeignKeyMeta fkey = new DForeignKeyMeta(this , fields);
043: fkey.refingRecord.refingFKeys.add(fkey);
044: fkey.refedRecord.refedFKeys.add(fkey);
045: fkey.name = fkey.refingRecord.getTableName() + "_"
046: + fkey.refingRecord.refingFKeys.size();
047: return fkey;
048: }
049:
050: public DFieldMeta getField(String name) {
051: return fields.get(name);
052: }
053:
054: public Collection<DFieldMeta> getFields() {
055: return Collections.unmodifiableCollection(fields.values());
056: }
057:
058: public Collection<DForeignKeyMeta> getRefingFKeys() {
059: return Collections.unmodifiableCollection(refingFKeys);
060: }
061:
062: public Collection<DForeignKeyMeta> getRefedFKeys() {
063: return Collections.unmodifiableCollection(refedFKeys);
064: }
065:
066: /** Called by DConnections, not directly by user. */
067: DRecordInstance newInstance() { // not SORM, in find/query record.
068: try {
069: return (DRecordInstance) clazz.newInstance();
070: } catch (Exception ex) {
071: throw new DException("While newing " + this , ex);
072: }
073: }
074:
075: /** nth primarykey, first is 0.
076: * Linear search, but nth is almost always 0. */
077: DFieldMeta primaryKeyField(int nth) {
078: int n0 = nth;
079: for (DFieldMeta field : fields.values()) {
080: if (field.isPrimaryKey() && nth-- == 0)
081: return field;
082: }
083: throw new DException("Not enough primary keys " + n0 + this );
084: }
085:
086: ////////
087:
088: public String getTableName() { // SORM
089: return tableName;
090: }
091:
092: public Class getClazz() { // sorm userClass, not public
093: return clazz;
094: }
095:
096: public Object getRecordImplementation() {
097: return recordImplementation;
098: }
099:
100: public void setRecordImplementation(Object recordImplementation) {
101: this.recordImplementation = recordImplementation;
102: }
103: }
|