1/* 2 * Copyright (C) 2008 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 libcore.sqlite; 18 19import SQLite.Database; 20import SQLite.Exception; 21import SQLite.Function; 22import SQLite.FunctionContext; 23import SQLite.Stmt; 24import SQLite.TableResult; 25import java.io.UnsupportedEncodingException; 26import java.sql.SQLException; 27import java.sql.Statement; 28import tests.support.DatabaseCreator; 29 30public final class OldFunctionContextTest extends OldSQLiteTest { 31 32 private Database db = null; 33 34 @Override public void setUp() throws java.lang.Exception { 35 super.setUp(); 36 db = new Database(); 37 db.open(dbFile.getPath(), 0); 38 Statement st = conn.createStatement(); 39 st.execute(DatabaseCreator.CREATE_TABLE2); 40 st.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1); 41 st.close(); 42 } 43 44 public void testSet_resultString() throws Exception { 45 TestFCString testString = new TestFCString(); 46 db.exec("insert into " + DatabaseCreator.TEST_TABLE2 47 + " (ftext) values ('TestInput')", null); 48 db.create_function("test", 1, testString); 49 TableResult res = db.get_table("select test(ftext) from " 50 + DatabaseCreator.TEST_TABLE2); 51 String row[] = (String[]) res.rows.elementAt(0); 52 String val = row[0]; 53 54 assertEquals("TestInput", val); 55 } 56 57 public void testSet_resultInt() throws Exception { 58 TestFCInt testInt = new TestFCInt(); 59 db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1 60 + " values (1,'" + testInt.intVal + "',3)", null); 61 db.create_function("testInt", 1, testInt); 62 TableResult res = db.get_table("select testInt(speed) from " 63 + DatabaseCreator.SIMPLE_TABLE1); 64 String row[] = (String[]) res.rows.elementAt(0); 65 String val = row[0]; 66 67 assertEquals(testInt.intVal, Integer.parseInt(val)); 68 } 69 70 public void testSet_resultDouble() throws Exception { 71 SinFunc testD = new SinFunc(); 72 db.exec("insert into " + DatabaseCreator.TEST_TABLE2 73 + " (fdouble) values (" + testD.testDouble + ")", null); 74 db.create_function("testDouble", 1, testD); 75 TableResult res = db.get_table("select testDouble(fdouble) from " 76 + DatabaseCreator.TEST_TABLE2); 77 String row[] = (String[]) res.rows.elementAt(0); 78 String val = row[0]; 79 80 assertEquals(testD.testDouble, Double.parseDouble(val)); 81 82 assertTrue(testD.functionCalled); 83 } 84 85 public void testSet_error() throws Exception { 86 TestFCError testError = new TestFCError(); 87 SinFunc testD = new SinFunc(); 88 db.exec("insert into " + DatabaseCreator.TEST_TABLE2 89 + " (fdouble) values (" + testD.testDouble + ")", null); 90 db.create_function("testError", 1, testError); 91 92 try { 93 TableResult res = db.get_table("select testError(fdouble) from " 94 + DatabaseCreator.TEST_TABLE2); 95 fail("Should get Exception"); 96 } catch (Exception e) { 97 assertEquals("error in step", e.getMessage()); 98 } 99 100 assertFalse(testD.functionCalled); 101 } 102 103 public void testSet_resultByteArray() throws Exception, UnsupportedEncodingException { 104 Stmt st = null; 105 TestFCByteArray testBinArrayFnc = new TestFCByteArray(); 106 String expected = ""; 107 expected = "X'" + getHexString(testBinArrayFnc.byteVal) + "'"; 108 109 // setup 110 db.exec("create table testBinaryData (binVal BINARY) ;", null); 111 112 try { 113 st = db.prepare("insert into testBinaryData values (?)"); 114 st.bind(1, testBinArrayFnc.byteVal); 115 st.step(); 116 117 118 db.create_function("testBinArray", 1, testBinArrayFnc); 119 TableResult res = db 120 .get_table("select testBinArray(binVal) from testBinaryData"); 121 122 String row[] = (String[]) res.rows.elementAt(0); 123 String val = row[0]; 124 125 assertTrue(expected.equalsIgnoreCase(val)); 126 127 assertTrue(testBinArrayFnc.functionCalled); 128 129 } finally { 130 //teardown 131 db.exec("drop table testBinaryData;", null); 132 } 133 } 134 135 /** 136 * ZeroBlob not supported 137 */ 138 public void testSet_result_zeroblob() throws Exception, 139 UnsupportedEncodingException { 140 Stmt st = null; 141 TestFCZeroBlob testZeroBlobFnc = new TestFCZeroBlob(); 142 byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3}; 143 144 145 // setup 146 db.exec("create table testBinaryData (binVal BINARY) ;", null); 147 148 try { 149 st = db.prepare("insert into testBinaryData values (?)"); 150 st.bind(1, byteVal); 151 st.step(); 152 153 154 db.create_function("testZeroBlob", 0, testZeroBlobFnc); 155 TableResult res = db 156 .get_table("select testZeroBlob() from testBinaryData"); 157 TableResult res2 = db.get_table("select zeroblob(" 158 + testZeroBlobFnc.numBytes + ") from testBinaryData"); 159 160 String row[] = (String[]) res.rows.elementAt(0); 161 String val = row[0]; 162 163 assertNotNull(val); 164 165 assertEquals(((String[]) res2.rows.elementAt(0))[0], val); 166 assertTrue(testZeroBlobFnc.functionCalled); 167 168 } finally { 169 // teardown 170 db.exec("drop table if exists testBinaryData;", null); 171 } 172 } 173 174 /** 175 * Test Method results in a segmentation fault 176 */ 177 public void testCount() throws SQLException, Exception { 178 TestFCCount countTest = new TestFCCount(); 179 int inputCount = 10; 180 181 assertFalse(countTest.functionCalled); 182 183 DatabaseCreator.fillTestTable2(conn, inputCount); 184 db.create_function("testCount", 0, countTest); 185 // the invokation of testCount leads to a Segmentation fault 186 /* 187 TableResult res = db 188 .get_table("select testCount() from "+DatabaseCreator.TEST_TABLE2); 189 190 String row[] = (String[]) res.rows.elementAt(0); 191 String val = row[0]; 192 193 assertTrue(countTest.functionCalled); 194 assertEquals(inputCount,Integer.parseInt(val)); 195 */ 196 197 } 198 199 class TestFCError implements Function { 200 public boolean functionCalled = false; 201 public String errorMsg = "FunctionError"; 202 203 public void function(FunctionContext fc, String args[]) { 204 functionCalled = true; 205 fc.set_error(errorMsg); 206 } 207 208 public void last_step(FunctionContext fc) {} 209 public void step(FunctionContext fc, String[] args) {} 210 } 211 212 class TestFCCount implements Function { 213 public boolean functionCalled = false; 214 public int noOfRows = 0; 215 216 public void function(FunctionContext fc, String args[]) { 217 functionCalled = true; 218 noOfRows = fc.count(); 219 fc.set_result(noOfRows); 220 } 221 222 public void last_step(FunctionContext fc) {} 223 public void step(FunctionContext fc, String[] args) {} 224 } 225 226 class TestFCZeroBlob implements Function { 227 public int numBytes = 16; 228 public boolean functionCalled = false; 229 230 public void function(FunctionContext fc, String args[]) { 231 functionCalled = true; 232 fc.set_result_zeroblob(numBytes); 233 } 234 235 public void last_step(FunctionContext fc) {} 236 public void step(FunctionContext fc, String[] args) {} 237 } 238 239 class TestFCString implements Function { 240 public String testString = "TestString"; 241 public boolean functionCalled; 242 243 public void function(FunctionContext fc, String args[]) { 244 assertNotNull(args); 245 functionCalled = true; 246 fc.set_result(args[0]); 247 } 248 249 public void last_step(FunctionContext fc) {} 250 public void step(FunctionContext fc, String[] args) {} 251 } 252 253 class TestFCInt implements Function { 254 public int intVal = Integer.MAX_VALUE; 255 public boolean functionCalled; 256 257 public void function(FunctionContext fc, String args[]) { 258 assertNotNull(args); 259 functionCalled = true; 260 fc.set_result(Integer.parseInt(args[0])); 261 } 262 263 public void last_step(FunctionContext fc) {} 264 public void step(FunctionContext fc, String[] args) {} 265 } 266 267 class TestFCByteArray implements Function { 268 public byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3}; 269 public boolean functionCalled; 270 271 public void function(FunctionContext fc, String args[]) { 272 assertNotNull(args); 273 functionCalled = true; 274 fc.set_result(args[0].getBytes()); 275 } 276 277 public void last_step(FunctionContext fc) {} 278 public void step(FunctionContext fc, String[] args) {} 279 } 280 281 class SinFunc implements Function { 282 public Double testDouble = 3.0; 283 public boolean functionCalled = false; 284 285 public void function(FunctionContext fc, String args[]) { 286 Double d = new Double(args[0]); 287 functionCalled = true; 288 fc.set_result(d.doubleValue()); 289 } 290 291 public void last_step(FunctionContext fc) {} 292 public void step(FunctionContext fc, String[] args) {} 293 } 294 295 static final byte[] HEX_CHAR_TABLE = { 296 (byte)'0', (byte)'1', (byte)'2', (byte)'3', 297 (byte)'4', (byte)'5', (byte)'6', (byte)'7', 298 (byte)'8', (byte)'9', (byte)'a', (byte)'b', 299 (byte)'c', (byte)'d', (byte)'e', (byte)'f' 300 }; 301 302 public static String getHexString(byte[] raw) 303 throws UnsupportedEncodingException { 304 byte[] hex = new byte[2 * raw.length]; 305 int index = 0; 306 307 for (byte b : raw) { 308 int v = b & 0xFF; 309 hex[index++] = HEX_CHAR_TABLE[v >>> 4]; 310 hex[index++] = HEX_CHAR_TABLE[v & 0xF]; 311 } 312 return new String(hex, "ASCII"); 313 } 314} 315