001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.dataAccess.db.converters;
019
020import io.stallion.dataAccess.Model;
021import io.stallion.dataAccess.db.Col;
022import io.stallion.dataAccess.db.DB;
023import io.stallion.dataAccess.db.Schema;
024import io.stallion.reflection.PropertyUtils;
025
026
027import java.math.BigInteger;
028import java.sql.Date;
029import java.sql.ResultSet;
030import java.sql.SQLException;
031import java.sql.Timestamp;
032import java.time.ZoneId;
033import java.time.ZonedDateTime;
034
035import static io.stallion.utils.Literals.empty;
036
037
038public interface ResultToModel<T extends Model> {
039    public Class getModelClass();
040    public Schema getSchema();
041
042    public default T handleOneRow(ResultSet resultSet) throws SQLException {
043        try {
044            T obj = (T)getModelClass().newInstance();
045            try {
046                Date date = resultSet.getDate("row_updated_at");
047                if (date != null) {
048                    obj.setLastModifiedMillis(date.getTime());
049                }
050            } catch (SQLException e) {
051
052            }
053            for (Col col : getSchema().getColumns()) {
054                Object value = resultSet.getObject(col.getName());
055
056                if (col.getConverter() != null) {
057                    value = col.getConverter().fromDb(obj, value, col.getName());
058                }
059                if (!empty(col.getConverterClassName())) {
060                    AttributeConverter converter = DB.instance().getConverter(col.getConverterClassName());
061                    value = converter.convertToEntityAttribute(value);
062                }
063                // MySQL driver returns bigint as BigInteger, despite it really being a Long sized field
064                if (value instanceof BigInteger) {
065                    value = ((BigInteger) value).longValue();
066                }
067                if (value instanceof Timestamp) {
068                    //value = ((Timestamp)value)
069                    value = ZonedDateTime.ofInstant(((Timestamp) value).toInstant(), ZoneId.of("UTC"));
070                }
071                if (value == null && col.getDefaultValue() != null) {
072                    value = col.getDefaultValue();
073                }
074                PropertyUtils.setProperty(obj, col.getPropertyName(), value);
075            }
076
077            Object idObj = resultSet.getObject("id");
078            Long id;
079            if (idObj instanceof BigInteger) {
080                id = ((BigInteger) idObj).longValue();
081            } else  {
082                id = (Long)idObj;
083            }
084            obj.setId(id);
085            return obj;
086        } catch (Exception e) {
087            throw new RuntimeException(e);
088        }
089    }
090}