1 /*
2  * Copyright (C) 2017 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 
17 package android.inputmethodservice.cts.db;
18 
19 import android.content.ContentValues;
20 import android.database.Cursor;
21 
22 /**
23  * Abstraction of SQLite database column.
24  */
25 public abstract class Field {
26 
27     /** Field position in a row. */
28     final int mPos;
29 
30     /** Column name of this field. */
31     final String mName;
32 
33     /** Field type of SQLite. */
34     final String mSqLiteType;
35 
newInstance(int pos, String name, int fieldType)36     static Field newInstance(int pos, String name, int fieldType) {
37         switch (fieldType) {
38             case Cursor.FIELD_TYPE_INTEGER:
39                 return new IntegerField(pos, name);
40             case Cursor.FIELD_TYPE_STRING:
41                 return new StringField(pos, name);
42             default:
43                 throw new IllegalArgumentException("Unknown field type: " + fieldType);
44         }
45     }
46 
Field(int pos, String name, int fieldType)47     private Field(int pos, String name, int fieldType) {
48         this.mPos = pos;
49         this.mName = name;
50         this.mSqLiteType = toSqLiteType(fieldType);
51     }
52 
53     /**
54      * Read data from {@link Cursor}.
55      *
56      * @param cursor {@link Cursor} to read.
57      * @return long data read from {@code cursor}.
58      */
getLong(Cursor cursor)59     public long getLong(Cursor cursor) {
60         throw buildException(Cursor.FIELD_TYPE_INTEGER);
61     }
62 
63     /**
64      * Read data from {@link Cursor}.
65      *
66      * @param cursor {@link Cursor} to read.
67      * @return {@link String} data read from {@code cursor}.
68      */
getString(Cursor cursor)69     public String getString(Cursor cursor) {
70         throw buildException(Cursor.FIELD_TYPE_STRING);
71     }
72 
73     /**
74      * Put data to {@link ContentValues}.
75      *
76      * @param values {@link ContentValues} to be updated.
77      * @param value long data to put.
78      */
putLong(ContentValues values, long value)79     public void putLong(ContentValues values, long value) {
80         throw buildException(Cursor.FIELD_TYPE_INTEGER);
81     }
82 
83     /**
84      * Put data to {@link ContentValues}.
85      *
86      * @param values {@link ContentValues} to be updated.
87      * @param value {@link String} data to put.
88      */
putString(ContentValues values, String value)89     public void putString(ContentValues values, String value) {
90         throw buildException(Cursor.FIELD_TYPE_STRING);
91     }
92 
buildException(int expectedFieldType)93     private UnsupportedOperationException buildException(int expectedFieldType) {
94         return new UnsupportedOperationException("Illegal type: " + mName + " is " + mSqLiteType
95                 + ", expected " + toSqLiteType(expectedFieldType));
96     }
97 
toSqLiteType(int fieldType)98     private static String toSqLiteType(int fieldType) {
99         switch (fieldType) {
100             case Cursor.FIELD_TYPE_NULL:
101                 return "NULL";
102             case Cursor.FIELD_TYPE_INTEGER:
103                 return "INTEGER";
104             case Cursor.FIELD_TYPE_FLOAT:
105                 return "REAL";
106             case Cursor.FIELD_TYPE_STRING:
107                 return "TEXT";
108             case Cursor.FIELD_TYPE_BLOB:
109                 return "BLOB";
110             default:
111                 throw new IllegalArgumentException("Unknown field type: " + fieldType);
112         }
113     }
114 
115     /**
116      * Abstraction of INTEGER type field.
117      */
118     private static final class IntegerField extends Field {
119 
IntegerField(int pos, String name)120         IntegerField(int pos, String name) {
121             super(pos, name, Cursor.FIELD_TYPE_INTEGER);
122         }
123 
124         @Override
getLong(Cursor cursor)125         public long getLong(Cursor cursor) {
126             return cursor.getLong(mPos);
127         }
128 
129         @Override
putLong(ContentValues values, long value)130         public void putLong(ContentValues values, long value) {
131             values.put(mName, value);
132         }
133     }
134 
135     /**
136      * Abstraction of STRING type field.
137      */
138     private static final class StringField extends Field {
139 
StringField(int pos, String name)140         StringField(int pos, String name) {
141             super(pos, name, Cursor.FIELD_TYPE_STRING);
142         }
143 
144         @Override
getString(Cursor cursor)145         public String getString(Cursor cursor) {
146             return cursor.getString(mPos);
147         }
148 
149         @Override
putString(ContentValues values, String value)150         public void putString(ContentValues values, String value) {
151             values.put(mName, value);
152         }
153     }
154 }
155