1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package androidx.room.solver.types
18
19import androidx.room.ext.L
20import androidx.room.ext.typeName
21import androidx.room.parser.SQLTypeAffinity
22import androidx.room.parser.SQLTypeAffinity.REAL
23import androidx.room.solver.CodeGenScope
24import javax.annotation.processing.ProcessingEnvironment
25import javax.lang.model.type.PrimitiveType
26import javax.lang.model.type.TypeKind.BYTE
27import javax.lang.model.type.TypeKind.CHAR
28import javax.lang.model.type.TypeKind.DOUBLE
29import javax.lang.model.type.TypeKind.FLOAT
30import javax.lang.model.type.TypeKind.INT
31import javax.lang.model.type.TypeKind.LONG
32import javax.lang.model.type.TypeKind.SHORT
33
34/**
35 * Adapters for all primitives that has direct cursor mappings.
36 */
37open class PrimitiveColumnTypeAdapter(out: PrimitiveType,
38                                      val cursorGetter: String,
39                                      val stmtSetter: String,
40                                      typeAffinity: SQLTypeAffinity)
41        : ColumnTypeAdapter(out, typeAffinity) {
42    val cast = if (cursorGetter == "get${out.typeName().toString().capitalize()}")
43                    ""
44                else
45                    "(${out.typeName()}) "
46
47    companion object {
48        fun createPrimitiveAdapters(
49                processingEnvironment: ProcessingEnvironment
50        ): List<PrimitiveColumnTypeAdapter> {
51            return listOf(
52                    Triple(INT, "getInt", "bindLong"),
53                    Triple(SHORT, "getShort", "bindLong"),
54                    Triple(BYTE, "getShort", "bindLong"),
55                    Triple(LONG, "getLong", "bindLong"),
56                    Triple(CHAR, "getInt", "bindLong"),
57                    Triple(FLOAT, "getFloat", "bindDouble"),
58                    Triple(DOUBLE, "getDouble", "bindDouble")
59            ).map {
60                PrimitiveColumnTypeAdapter(
61                        out = processingEnvironment.typeUtils.getPrimitiveType(it.first),
62                        cursorGetter = it.second,
63                        stmtSetter = it.third,
64                        typeAffinity = when (it.first) {
65                            INT, SHORT, BYTE, LONG, CHAR -> SQLTypeAffinity.INTEGER
66                            FLOAT, DOUBLE -> REAL
67                            else -> throw IllegalArgumentException("invalid type")
68                        }
69                )
70            }
71        }
72    }
73
74    override fun bindToStmt(stmtName: String, indexVarName: String, valueVarName: String,
75                            scope: CodeGenScope) {
76        scope.builder()
77                .addStatement("$L.$L($L, $L)", stmtName, stmtSetter, indexVarName, valueVarName)
78    }
79
80    override fun readFromCursor(outVarName: String, cursorVarName: String, indexVarName: String,
81                                scope: CodeGenScope) {
82        scope.builder()
83                .addStatement("$L = $L$L.$L($L)", outVarName, cast, cursorVarName,
84                        cursorGetter, indexVarName)
85    }
86}
87