// Path: src/main/java/com/jajja/jorm/Composite.java
// public static class Value {
//     private Composite composite;
//     private Object[] values;
// 
//     private Value(Composite composite, Object ... values) {
//         this.composite = composite;
//         this.values = values;
//     }
// 
//     public Composite getComposite() {
//         return composite;
//     }
// 
//     public Object[] getValues() {
//         return values;
//     }
// 
//     public Object getValue() {
//         if (!isSingle()) {
//             throw new RuntimeException("Not a single column key");
//         }
//         return values[0];
//     }
// 
//     private int getOffset(String column) {
//         for (int i = 0; i < composite.columns.length; i++) {
//             if (composite.columns[i].equals(column)) {
//                 return i;
//             }
//         }
//         return -1;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T get(String column, Class<T> clazz) {
//         int offset = getOffset(column);
//         if (offset < 0) {
//             throw new IllegalArgumentException("No such column " + column);
//         }
//         Object value = values[offset];
//         if (value == null) {
//             return null;
//         }
//         return (T)value;
//     }
// 
//     public boolean isSingle() {
//         return values.length == 1;
//     }
// 
//     @Override
//     public int hashCode() {
//         int hashCode = 0;
//         for (Object value : values) {
//             if (value != null) {
//                 hashCode += value.hashCode();
//             }
//         }
//         return hashCode;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (obj instanceof Value) {
//             Value v = (Value)obj;
//             if (values.length != v.values.length) {
//                 return false;
//             }
//             for (int i = 0; i < values.length; i++) {
//                 if (!((values[i] == v.values[i]) || (values[i] != null && values[i].equals(v.values[i])))) {
//                     return false;
//                 }
//             }
//             return true;
//         }
//         return false;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder(16 * values.length);
//         sb.append("{");
//         boolean isFirst = true;
//         for (Object value : values) {
//             if (!isFirst) {
//                 sb.append(", ");
//             } else {
//                 isFirst = false;
//             }
//             sb.append(value);
//         }
//         sb.append("}");
//         return sb.toString();
//     }
// }


import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.jajja.jorm.Composite.Value;
/*
 * Copyright (C) 2013 Jajja Communications AB
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.jajja.jorm;



/**
 * A record cache implementation, using LRU.
 *
 * @see Record
 * @author Andreas Allerdahl &lt;andreas.allerdahl@jajja.com&gt;
 * @since 1.0.0
 */
public class Cache<C extends Record> {
    private Lru<Object> map;
    private Class<C> clazz;
    private Set<Composite> additionalComposites = new HashSet<Composite>();
    private Composite primaryKey;
    // <additionalComposite, <additionalValue, primaryKeyValue>>
// Path: src/main/java/com/jajja/jorm/Composite.java
// public static class Value {
//     private Composite composite;
//     private Object[] values;
// 
//     private Value(Composite composite, Object ... values) {
//         this.composite = composite;
//         this.values = values;
//     }
// 
//     public Composite getComposite() {
//         return composite;
//     }
// 
//     public Object[] getValues() {
//         return values;
//     }
// 
//     public Object getValue() {
//         if (!isSingle()) {
//             throw new RuntimeException("Not a single column key");
//         }
//         return values[0];
//     }
// 
//     private int getOffset(String column) {
//         for (int i = 0; i < composite.columns.length; i++) {
//             if (composite.columns[i].equals(column)) {
//                 return i;
//             }
//         }
//         return -1;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T get(String column, Class<T> clazz) {
//         int offset = getOffset(column);
//         if (offset < 0) {
//             throw new IllegalArgumentException("No such column " + column);
//         }
//         Object value = values[offset];
//         if (value == null) {
//             return null;
//         }
//         return (T)value;
//     }
// 
//     public boolean isSingle() {
//         return values.length == 1;
//     }
// 
//     @Override
//     public int hashCode() {
//         int hashCode = 0;
//         for (Object value : values) {
//             if (value != null) {
//                 hashCode += value.hashCode();
//             }
//         }
//         return hashCode;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (obj instanceof Value) {
//             Value v = (Value)obj;
//             if (values.length != v.values.length) {
//                 return false;
//             }
//             for (int i = 0; i < values.length; i++) {
//                 if (!((values[i] == v.values[i]) || (values[i] != null && values[i].equals(v.values[i])))) {
//                     return false;
//                 }
//             }
//             return true;
//         }
//         return false;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder(16 * values.length);
//         sb.append("{");
//         boolean isFirst = true;
//         for (Object value : values) {
//             if (!isFirst) {
//                 sb.append(", ");
//             } else {
//                 isFirst = false;
//             }
//             sb.append(value);
//         }
//         sb.append("}");
//         return sb.toString();
//     }
// }


// Path: src/main/java/com/jajja/jorm/Cache.java
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.jajja.jorm.Composite.Value;

/*
 * Copyright (C) 2013 Jajja Communications AB
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.jajja.jorm;



/**
 * A record cache implementation, using LRU.
 *
 * @see Record
 * @author Andreas Allerdahl &lt;andreas.allerdahl@jajja.com&gt;
 * @since 1.0.0
 */
public class Cache<C extends Record> {
    private Lru<Object> map;
    private Class<C> clazz;
    private Set<Composite> additionalComposites = new HashSet<Composite>();
    private Composite primaryKey;
    // <additionalComposite, <additionalValue, primaryKeyValue>>
    private Map<Composite, Map<Composite.Value, Composite.Value>> additionalMap = new HashMap<Composite, Map<Composite.Value, Composite.Value>>();