aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/service/BaseJdbcService.java
blob: d16dadd2872077126764c278c2fcd33575f95f56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Copyright (C) 2008-2023, Juick
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.juick.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import javax.inject.Inject;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

/**
 * Created by aalexeev on 11/13/16.
 */
public class BaseJdbcService {
    @Inject
    JdbcTemplate jdbcTemplate;
    @Inject
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    @Value("#{new Boolean('${spring.sql.init.platform}' == 'sqlserver')}")
    private boolean omitRecursiveKeyword;
    @Value("#{('${spring.sql.init.platform}' == 'sqlite') or ('${spring.sql.init.platform}' == 'mysql')}")
    // Added in MariaDB 10.6
    private boolean haveNoANSIFetch;
    @Value("#{new Boolean('${spring.sql.init.platform}' == 'sqlite')}")
    private boolean haveNoDates;
    @Value("#{new Boolean('${spring.sql.init.platform}' == 'sqlite')}")
    private boolean haveNoGreatest;
    @Value("#{new Boolean('${spring.sql.init.platform}' == 'sqlite')}")
    private boolean haveNoForUpdate;
    @Value("#{new Boolean('${spring.sql.init.platform}' == 'mysql')}")
    private boolean haveNoOffsetDateTime;

    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
        return namedParameterJdbcTemplate;
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public String withRecursive() {
        return omitRecursiveKeyword ? "WITH" : "WITH RECURSIVE";
    }

    protected String limit(int rows) {
        if (haveNoANSIFetch) {
            return "LIMIT " + rows;
        } else {
            return "OFFSET 0 ROWS FETCH NEXT " + rows + " ROWS ONLY";
        }
    }
    protected String greatest() {
        if (haveNoGreatest) {
            return "MAX";
        }
        return "GREATEST";
    }
    protected String forUpdate() {
        if (haveNoForUpdate) {
            return "";
        }
        return "FOR UPDATE";
    }
    public OffsetDateTime getOffsetDateTime(ResultSet rs, int columnIndex) throws SQLException {
        if (haveNoDates) {
            var date = rs.getLong(columnIndex);
            if (date != 0) {
                return Instant.ofEpochMilli(date).atOffset(ZoneOffset.UTC);
            }
            return null;
        }
        if (haveNoOffsetDateTime) {
            var date = rs.getTimestamp(columnIndex);
            if (date != null) {
                return date.toInstant().atOffset(ZoneOffset.UTC);
            }
            return null;
        }
        return rs.getObject(columnIndex, OffsetDateTime.class);
    }
    public Object fromEpochMilli(Long milliseconds) {
        if (haveNoDates) {
            return milliseconds;
        }
        if (haveNoOffsetDateTime) {
            return new Timestamp(milliseconds);
        }
        return Instant.ofEpochMilli(milliseconds).atOffset(ZoneOffset.UTC);
    }
    public Object toDateTime(OffsetDateTime now) {
        if (haveNoDates) {
            return now.toInstant().toEpochMilli();
        }
        return now;
    }
    public int dateTimeType() {
        if (haveNoDates) {
            return Types.INTEGER;
        }
        if (haveNoOffsetDateTime) {
            return Types.TIMESTAMP;
        }
        return Types.TIMESTAMP_WITH_TIMEZONE;
    }
}