All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pers.clare.hisql.store.SQLStoreFactory Maven / Gradle / Ivy

The newest version!
package pers.clare.hisql.store;

import pers.clare.hisql.exception.HiSqlException;
import pers.clare.hisql.function.FieldSetter;
import pers.clare.hisql.function.KeySQLBuilder;
import pers.clare.hisql.function.ResultSetValueConverter;
import pers.clare.hisql.naming.NamingStrategy;
import pers.clare.hisql.support.ResultSetConverter;
import pers.clare.hisql.util.ClassUtil;
import pers.clare.hisql.util.FieldColumnFactory;
import pers.clare.hisql.util.SQLQueryUtil;

import javax.persistence.Table;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@SuppressWarnings("unused")
public class SQLStoreFactory {

    static final Map, SQLStore> storeCacheMap = new ConcurrentHashMap<>();
    static final Map, Map>> converterFieldSetMap = new ConcurrentHashMap<>();

    public static  KeySQLBuilder buildKey(Class keyClass, SQLCrudStore store) {
        if (ClassUtil.isBasicType(keyClass)
            || keyClass.isArray()
        ) {
            return (builder, key) -> SQLQueryUtil.setValue(builder, store.getKeyFields(), new Object[]{key});
        } else {
            Field[] keyFields = new Field[store.getKeyFields().length];
            int count = 0;
            for (Field field : store.getKeyFields()) {
                try {
                    Field keyField = keyFields[count++] = keyClass.getDeclaredField(field.getName());
                    keyField.setAccessible(true);
                } catch (NoSuchFieldException e) {
                    throw new IllegalArgumentException(String.format("%s %s field not found!", keyClass, field.getName()));
                }
            }
            return (builder, key) -> SQLQueryUtil.setValue(builder, keyFields, key);
        }
    }

    @SuppressWarnings("unchecked")
    public static  SQLStore build(
            NamingStrategy naming
            , ResultSetConverter converter
            , Class clazz
    ) {
        if (FieldColumnFactory.isIgnore(clazz)) throw new Error(String.format("%s can not build SQLStore", clazz));
        return (SQLStore) storeCacheMap.computeIfAbsent(clazz, (key) -> doBuild(naming, converter, clazz));
    }

    @SuppressWarnings("unchecked")
    public static  SQLCrudStore buildCrud(
            NamingStrategy naming
            , ResultSetConverter converter
            , Class clazz
    ) {
        if (FieldColumnFactory.isIgnore(clazz))
            throw new Error(String.format("%s can not build SQLSchemaStore", clazz));
        SQLStore store = (SQLStore) storeCacheMap.get(clazz);
        if (!(store instanceof SQLCrudStore)) {
            store = doBuildCrud(naming, converter, clazz);
            storeCacheMap.put(clazz, store);
        }
        return (SQLCrudStore) store;
    }

    private static  SQLStore doBuild(
            NamingStrategy naming
            , ResultSetConverter converter
            , Class clazz
    ) {
        try {
            return new SQLStore<>(clazz.getConstructor(), buildFieldSetters(naming, clazz, converter));
        } catch (NoSuchMethodException e) {
            throw new HiSqlException(e.getMessage());
        }
    }

    private static  SQLCrudStore doBuildCrud(
            NamingStrategy naming
            , ResultSetConverter converter
            , Class clazz
    ) {
        String tableName;
        Table table = clazz.getAnnotation(Table.class);
        if (table == null) {
            tableName = naming.turnCamelCase(clazz.getSimpleName());
        } else {
            tableName = table.name();
        }
        FieldColumn[] fieldColumns = FieldColumnFactory.get(naming, clazz);
        int length = fieldColumns.length;
        int keyCount = 0;
        Field[] keyFields = new Field[length];
        Field autoKey = null;
        boolean ps = false;
        for (FieldColumn column : fieldColumns) {
            if (column.isAuto()) autoKey = column.getField();
            if (column.isId()) {
                keyFields[keyCount++] = column.getField();
            }
            if (InputStream.class.isAssignableFrom(column.getField().getType())) {
                ps = true;
            }

        }
        Field[] temp = keyFields;
        keyFields = new Field[keyCount];
        System.arraycopy(temp, 0, keyFields, 0, keyCount);

        try {
            return new SQLCrudStore<>(clazz.getConstructor()
                    , buildFieldSetters(naming, clazz, converter)
                    , tableName, fieldColumns, autoKey, keyFields, ps
            );
        } catch (NoSuchMethodException e) {
            throw new HiSqlException(e.getMessage());
        }
    }

    private static Map buildFieldSetters(NamingStrategy naming, Class clazz, ResultSetConverter converter) {
        return converterFieldSetMap.computeIfAbsent(converter, (c) -> new ConcurrentHashMap<>()).computeIfAbsent(clazz, (key) -> {
            FieldColumn[] fields = FieldColumnFactory.get(naming, clazz);
            Map fieldSetMap = new ConcurrentHashMap<>();
            for (FieldColumn fieldColumn : fields) {
                Field field = fieldColumn.getField();
                String name = fieldColumn.getColumnName().replaceAll("`", "");
                FieldSetter fieldSetter = buildFieldSetter(converter, field);
                fieldSetMap.put(field.getName(), fieldSetter);
                fieldSetMap.put(name, fieldSetter);
                fieldSetMap.put(name.toUpperCase(), fieldSetter);
            }
            return fieldSetMap;
        });
    }

    private static FieldSetter buildFieldSetter(ResultSetConverter resultSetConverter, Field field) {
        ResultSetValueConverter valueConverter = resultSetConverter.get(field.getType());
        if (valueConverter == null) {
            if (field.getType() == Object.class) {
                return (target, rs, index) -> field.set(target, rs.getObject(index));
            } else {
                return (target, rs, index) -> field.set(target, rs.getObject(index, field.getType()));
            }
        } else {
            return (target, rs, index) -> field.set(target, valueConverter.apply(rs, index));
        }
    }

    private static char[] merge(String... strings) {
        int size = 0;
        for (String string : strings) {
            size += string.length();
        }
        char[] cs = new char[size];
        int i = 0;
        for (String string : strings) {
            string.getChars(0, string.length(), cs, i);
            i += string.length();
        }
        return cs;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy