SQLite Android Bindings
Hex Artifact Content
Not logged in

Artifact 68492ffcc6896e737324fb0b9a9bd4dee1e8e9b5:


0000: 2f 2a 0a 20 2a 20 43 6f 70 79 72 69 67 68 74 20  /*. * Copyright 
0010: 28 43 29 20 32 30 30 39 20 54 68 65 20 41 6e 64  (C) 2009 The And
0020: 72 6f 69 64 20 4f 70 65 6e 20 53 6f 75 72 63 65  roid Open Source
0030: 20 50 72 6f 6a 65 63 74 0a 20 2a 0a 20 2a 20 4c   Project. *. * L
0040: 69 63 65 6e 73 65 64 20 75 6e 64 65 72 20 74 68  icensed under th
0050: 65 20 41 70 61 63 68 65 20 4c 69 63 65 6e 73 65  e Apache License
0060: 2c 20 56 65 72 73 69 6f 6e 20 32 2e 30 20 28 74  , Version 2.0 (t
0070: 68 65 20 22 4c 69 63 65 6e 73 65 22 29 3b 0a 20  he "License");. 
0080: 2a 20 79 6f 75 20 6d 61 79 20 6e 6f 74 20 75 73  * you may not us
0090: 65 20 74 68 69 73 20 66 69 6c 65 20 65 78 63 65  e this file exce
00a0: 70 74 20 69 6e 20 63 6f 6d 70 6c 69 61 6e 63 65  pt in compliance
00b0: 20 77 69 74 68 20 74 68 65 20 4c 69 63 65 6e 73   with the Licens
00c0: 65 2e 0a 20 2a 20 59 6f 75 20 6d 61 79 20 6f 62  e.. * You may ob
00d0: 74 61 69 6e 20 61 20 63 6f 70 79 20 6f 66 20 74  tain a copy of t
00e0: 68 65 20 4c 69 63 65 6e 73 65 20 61 74 0a 20 2a  he License at. *
00f0: 0a 20 2a 20 20 20 20 20 20 68 74 74 70 3a 2f 2f  . *      http://
0100: 77 77 77 2e 61 70 61 63 68 65 2e 6f 72 67 2f 6c  www.apache.org/l
0110: 69 63 65 6e 73 65 73 2f 4c 49 43 45 4e 53 45 2d  icenses/LICENSE-
0120: 32 2e 30 0a 20 2a 0a 20 2a 20 55 6e 6c 65 73 73  2.0. *. * Unless
0130: 20 72 65 71 75 69 72 65 64 20 62 79 20 61 70 70   required by app
0140: 6c 69 63 61 62 6c 65 20 6c 61 77 20 6f 72 20 61  licable law or a
0150: 67 72 65 65 64 20 74 6f 20 69 6e 20 77 72 69 74  greed to in writ
0160: 69 6e 67 2c 20 73 6f 66 74 77 61 72 65 0a 20 2a  ing, software. *
0170: 20 64 69 73 74 72 69 62 75 74 65 64 20 75 6e 64   distributed und
0180: 65 72 20 74 68 65 20 4c 69 63 65 6e 73 65 20 69  er the License i
0190: 73 20 64 69 73 74 72 69 62 75 74 65 64 20 6f 6e  s distributed on
01a0: 20 61 6e 20 22 41 53 20 49 53 22 20 42 41 53 49   an "AS IS" BASI
01b0: 53 2c 0a 20 2a 20 57 49 54 48 4f 55 54 20 57 41  S,. * WITHOUT WA
01c0: 52 52 41 4e 54 49 45 53 20 4f 52 20 43 4f 4e 44  RRANTIES OR COND
01d0: 49 54 49 4f 4e 53 20 4f 46 20 41 4e 59 20 4b 49  ITIONS OF ANY KI
01e0: 4e 44 2c 20 65 69 74 68 65 72 20 65 78 70 72 65  ND, either expre
01f0: 73 73 20 6f 72 20 69 6d 70 6c 69 65 64 2e 0a 20  ss or implied.. 
0200: 2a 20 53 65 65 20 74 68 65 20 4c 69 63 65 6e 73  * See the Licens
0210: 65 20 66 6f 72 20 74 68 65 20 73 70 65 63 69 66  e for the specif
0220: 69 63 20 6c 61 6e 67 75 61 67 65 20 67 6f 76 65  ic language gove
0230: 72 6e 69 6e 67 20 70 65 72 6d 69 73 73 69 6f 6e  rning permission
0240: 73 20 61 6e 64 0a 20 2a 20 6c 69 6d 69 74 61 74  s and. * limitat
0250: 69 6f 6e 73 20 75 6e 64 65 72 20 74 68 65 20 4c  ions under the L
0260: 69 63 65 6e 73 65 2e 0a 20 2a 2f 0a 0a 70 61 63  icense.. */..pac
0270: 6b 61 67 65 20 6f 72 67 2e 73 71 6c 69 74 65 2e  kage org.sqlite.
0280: 64 61 74 61 62 61 73 65 2e 73 71 6c 69 74 65 5f  database.sqlite_
0290: 63 74 73 3b 0a 0a 0a 69 6d 70 6f 72 74 20 61 6e  cts;...import an
02a0: 64 72 6f 69 64 2e 63 6f 6e 74 65 6e 74 2e 43 6f  droid.content.Co
02b0: 6e 74 65 78 74 3b 0a 69 6d 70 6f 72 74 20 61 6e  ntext;.import an
02c0: 64 72 6f 69 64 2e 64 61 74 61 62 61 73 65 2e 43  droid.database.C
02d0: 75 72 73 6f 72 3b 0a 69 6d 70 6f 72 74 20 6f 72  ursor;.import or
02e0: 67 2e 73 71 6c 69 74 65 2e 64 61 74 61 62 61 73  g.sqlite.databas
02f0: 65 2e 73 71 6c 69 74 65 2e 53 51 4c 69 74 65 43  e.sqlite.SQLiteC
0300: 75 72 73 6f 72 3b 0a 69 6d 70 6f 72 74 20 6f 72  ursor;.import or
0310: 67 2e 73 71 6c 69 74 65 2e 64 61 74 61 62 61 73  g.sqlite.databas
0320: 65 2e 73 71 6c 69 74 65 2e 53 51 4c 69 74 65 43  e.sqlite.SQLiteC
0330: 75 72 73 6f 72 44 72 69 76 65 72 3b 0a 69 6d 70  ursorDriver;.imp
0340: 6f 72 74 20 6f 72 67 2e 73 71 6c 69 74 65 2e 64  ort org.sqlite.d
0350: 61 74 61 62 61 73 65 2e 73 71 6c 69 74 65 2e 53  atabase.sqlite.S
0360: 51 4c 69 74 65 44 61 74 61 62 61 73 65 3b 0a 69  QLiteDatabase;.i
0370: 6d 70 6f 72 74 20 6f 72 67 2e 73 71 6c 69 74 65  mport org.sqlite
0380: 2e 64 61 74 61 62 61 73 65 2e 73 71 6c 69 74 65  .database.sqlite
0390: 2e 53 51 4c 69 74 65 51 75 65 72 79 3b 0a 69 6d  .SQLiteQuery;.im
03a0: 70 6f 72 74 20 6f 72 67 2e 73 71 6c 69 74 65 2e  port org.sqlite.
03b0: 64 61 74 61 62 61 73 65 2e 73 71 6c 69 74 65 2e  database.sqlite.
03c0: 53 51 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64  SQLiteQueryBuild
03d0: 65 72 3b 0a 69 6d 70 6f 72 74 20 61 6e 64 72 6f  er;.import andro
03e0: 69 64 2e 6f 73 2e 43 61 6e 63 65 6c 6c 61 74 69  id.os.Cancellati
03f0: 6f 6e 53 69 67 6e 61 6c 3b 0a 69 6d 70 6f 72 74  onSignal;.import
0400: 20 61 6e 64 72 6f 69 64 2e 6f 73 2e 4f 70 65 72   android.os.Oper
0410: 61 74 69 6f 6e 43 61 6e 63 65 6c 65 64 45 78 63  ationCanceledExc
0420: 65 70 74 69 6f 6e 3b 0a 69 6d 70 6f 72 74 20 61  eption;.import a
0430: 6e 64 72 6f 69 64 2e 74 65 73 74 2e 41 6e 64 72  ndroid.test.Andr
0440: 6f 69 64 54 65 73 74 43 61 73 65 3b 0a 0a 69 6d  oidTestCase;..im
0450: 70 6f 72 74 20 6a 61 76 61 2e 75 74 69 6c 2e 48  port java.util.H
0460: 61 73 68 4d 61 70 3b 0a 69 6d 70 6f 72 74 20 6a  ashMap;.import j
0470: 61 76 61 2e 75 74 69 6c 2e 4d 61 70 3b 0a 69 6d  ava.util.Map;.im
0480: 70 6f 72 74 20 6a 61 76 61 2e 75 74 69 6c 2e 63  port java.util.c
0490: 6f 6e 63 75 72 72 65 6e 74 2e 53 65 6d 61 70 68  oncurrent.Semaph
04a0: 6f 72 65 3b 0a 69 6d 70 6f 72 74 20 6a 61 76 61  ore;.import java
04b0: 2e 69 6f 2e 46 69 6c 65 3b 0a 0a 70 75 62 6c 69  .io.File;..publi
04c0: 63 20 63 6c 61 73 73 20 53 51 4c 69 74 65 51 75  c class SQLiteQu
04d0: 65 72 79 42 75 69 6c 64 65 72 54 65 73 74 20 65  eryBuilderTest e
04e0: 78 74 65 6e 64 73 20 41 6e 64 72 6f 69 64 54 65  xtends AndroidTe
04f0: 73 74 43 61 73 65 20 7b 0a 20 20 20 20 70 72 69  stCase {.    pri
0500: 76 61 74 65 20 53 51 4c 69 74 65 44 61 74 61 62  vate SQLiteDatab
0510: 61 73 65 20 6d 44 61 74 61 62 61 73 65 3b 0a 20  ase mDatabase;. 
0520: 20 20 20 70 72 69 76 61 74 65 20 66 69 6e 61 6c     private final
0530: 20 53 74 72 69 6e 67 20 54 45 53 54 5f 54 41 42   String TEST_TAB
0540: 4c 45 5f 4e 41 4d 45 20 3d 20 22 74 65 73 74 22  LE_NAME = "test"
0550: 3b 0a 20 20 20 20 70 72 69 76 61 74 65 20 66 69  ;.    private fi
0560: 6e 61 6c 20 53 74 72 69 6e 67 20 45 4d 50 4c 4f  nal String EMPLO
0570: 59 45 45 5f 54 41 42 4c 45 5f 4e 41 4d 45 20 3d  YEE_TABLE_NAME =
0580: 20 22 65 6d 70 6c 6f 79 65 65 22 3b 0a 20 20 20   "employee";.   
0590: 20 70 72 69 76 61 74 65 20 73 74 61 74 69 63 20   private static 
05a0: 66 69 6e 61 6c 20 53 74 72 69 6e 67 20 44 41 54  final String DAT
05b0: 41 42 41 53 45 5f 46 49 4c 45 20 3d 20 22 64 61  ABASE_FILE = "da
05c0: 74 61 62 61 73 65 5f 74 65 73 74 2e 64 62 22 3b  tabase_test.db";
05d0: 0a 0a 20 20 20 20 40 4f 76 65 72 72 69 64 65 0a  ..    @Override.
05e0: 20 20 20 20 70 72 6f 74 65 63 74 65 64 20 76 6f      protected vo
05f0: 69 64 20 73 65 74 55 70 28 29 20 74 68 72 6f 77  id setUp() throw
0600: 73 20 45 78 63 65 70 74 69 6f 6e 20 7b 0a 20 20  s Exception {.  
0610: 20 20 20 20 20 20 73 75 70 65 72 2e 73 65 74 55        super.setU
0620: 70 28 29 3b 0a 20 20 20 20 20 20 20 20 53 79 73  p();.        Sys
0630: 74 65 6d 2e 6c 6f 61 64 4c 69 62 72 61 72 79 28  tem.loadLibrary(
0640: 22 73 71 6c 69 74 65 58 22 29 3b 0a 20 20 20 20  "sqliteX");.    
0650: 20 20 20 20 46 69 6c 65 20 66 20 3d 20 6d 43 6f      File f = mCo
0660: 6e 74 65 78 74 2e 67 65 74 44 61 74 61 62 61 73  ntext.getDatabas
0670: 65 50 61 74 68 28 44 41 54 41 42 41 53 45 5f 46  ePath(DATABASE_F
0680: 49 4c 45 29 3b 0a 20 20 20 20 20 20 20 20 66 2e  ILE);.        f.
0690: 6d 6b 64 69 72 73 28 29 3b 0a 20 20 20 20 20 20  mkdirs();.      
06a0: 20 20 69 66 20 28 66 2e 65 78 69 73 74 73 28 29    if (f.exists()
06b0: 29 20 7b 20 66 2e 64 65 6c 65 74 65 28 29 3b 20  ) { f.delete(); 
06c0: 7d 0a 20 20 20 20 20 20 20 20 6d 44 61 74 61 62  }.        mDatab
06d0: 61 73 65 20 3d 20 53 51 4c 69 74 65 44 61 74 61  ase = SQLiteData
06e0: 62 61 73 65 2e 6f 70 65 6e 4f 72 43 72 65 61 74  base.openOrCreat
06f0: 65 44 61 74 61 62 61 73 65 28 66 2c 6e 75 6c 6c  eDatabase(f,null
0700: 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  );.        asser
0710: 74 4e 6f 74 4e 75 6c 6c 28 6d 44 61 74 61 62 61  tNotNull(mDataba
0720: 73 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  se);.    }..    
0730: 40 4f 76 65 72 72 69 64 65 0a 20 20 20 20 70 72  @Override.    pr
0740: 6f 74 65 63 74 65 64 20 76 6f 69 64 20 74 65 61  otected void tea
0750: 72 44 6f 77 6e 28 29 20 74 68 72 6f 77 73 20 45  rDown() throws E
0760: 78 63 65 70 74 69 6f 6e 20 7b 0a 20 20 20 20 20  xception {.     
0770: 20 20 20 6d 44 61 74 61 62 61 73 65 2e 63 6c 6f     mDatabase.clo
0780: 73 65 28 29 3b 0a 20 20 20 20 20 20 20 20 67 65  se();.        ge
0790: 74 43 6f 6e 74 65 78 74 28 29 2e 64 65 6c 65 74  tContext().delet
07a0: 65 44 61 74 61 62 61 73 65 28 44 41 54 41 42 41  eDatabase(DATABA
07b0: 53 45 5f 46 49 4c 45 29 3b 0a 20 20 20 20 20 20  SE_FILE);.      
07c0: 20 20 73 75 70 65 72 2e 74 65 61 72 44 6f 77 6e    super.tearDown
07d0: 28 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70  ();.    }..    p
07e0: 75 62 6c 69 63 20 76 6f 69 64 20 74 65 73 74 43  ublic void testC
07f0: 6f 6e 73 74 72 75 63 74 6f 72 28 29 20 7b 0a 20  onstructor() {. 
0800: 20 20 20 20 20 20 20 6e 65 77 20 53 51 4c 69 74         new SQLit
0810: 65 51 75 65 72 79 42 75 69 6c 64 65 72 28 29 3b  eQueryBuilder();
0820: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 75 62 6c  .    }..    publ
0830: 69 63 20 76 6f 69 64 20 74 65 73 74 53 65 74 44  ic void testSetD
0840: 69 73 74 69 6e 63 74 28 29 20 7b 0a 20 20 20 20  istinct() {.    
0850: 20 20 20 20 53 74 72 69 6e 67 20 65 78 70 65 63      String expec
0860: 74 65 64 3b 0a 20 20 20 20 20 20 20 20 53 51 4c  ted;.        SQL
0870: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20  iteQueryBuilder 
0880: 73 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64  sqliteQueryBuild
0890: 65 72 20 3d 20 6e 65 77 20 53 51 4c 69 74 65 51  er = new SQLiteQ
08a0: 75 65 72 79 42 75 69 6c 64 65 72 28 29 3b 0a 20  ueryBuilder();. 
08b0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 51 75 65         sqliteQue
08c0: 72 79 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62  ryBuilder.setTab
08d0: 6c 65 73 28 54 45 53 54 5f 54 41 42 4c 45 5f 4e  les(TEST_TABLE_N
08e0: 41 4d 45 29 3b 0a 20 20 20 20 20 20 20 20 73 71  AME);.        sq
08f0: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
0900: 2e 73 65 74 44 69 73 74 69 6e 63 74 28 66 61 6c  .setDistinct(fal
0910: 73 65 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  se);.        sql
0920: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e  iteQueryBuilder.
0930: 61 70 70 65 6e 64 57 68 65 72 65 28 22 61 67 65  appendWhere("age
0940: 3d 32 30 22 29 3b 0a 20 20 20 20 20 20 20 20 53  =20");.        S
0950: 74 72 69 6e 67 20 73 71 6c 20 3d 20 73 71 6c 69  tring sql = sqli
0960: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 62  teQueryBuilder.b
0970: 75 69 6c 64 51 75 65 72 79 28 6e 65 77 20 53 74  uildQuery(new St
0980: 72 69 6e 67 5b 5d 20 7b 20 22 61 67 65 22 2c 20  ring[] { "age", 
0990: 22 61 64 64 72 65 73 73 22 20 7d 2c 0a 20 20 20  "address" },.   
09a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6e 75 6c               nul
09b0: 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e  l, null, null, n
09c0: 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 29  ull, null, null)
09d0: 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
09e0: 45 71 75 61 6c 73 28 54 45 53 54 5f 54 41 42 4c  Equals(TEST_TABL
09f0: 45 5f 4e 41 4d 45 2c 20 73 71 6c 69 74 65 51 75  E_NAME, sqliteQu
0a00: 65 72 79 42 75 69 6c 64 65 72 2e 67 65 74 54 61  eryBuilder.getTa
0a10: 62 6c 65 73 28 29 29 3b 0a 20 20 20 20 20 20 20  bles());.       
0a20: 20 65 78 70 65 63 74 65 64 20 3d 20 22 53 45 4c   expected = "SEL
0a30: 45 43 54 20 61 67 65 2c 20 61 64 64 72 65 73 73  ECT age, address
0a40: 20 46 52 4f 4d 20 22 20 2b 20 54 45 53 54 5f 54   FROM " + TEST_T
0a50: 41 42 4c 45 5f 4e 41 4d 45 20 2b 20 22 20 57 48  ABLE_NAME + " WH
0a60: 45 52 45 20 28 61 67 65 3d 32 30 29 22 3b 0a 20  ERE (age=20)";. 
0a70: 20 20 20 20 20 20 20 61 73 73 65 72 74 45 71 75         assertEqu
0a80: 61 6c 73 28 65 78 70 65 63 74 65 64 2c 20 73 71  als(expected, sq
0a90: 6c 29 3b 0a 0a 20 20 20 20 20 20 20 20 73 71 6c  l);..        sql
0aa0: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20  iteQueryBuilder 
0ab0: 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75 65 72  = new SQLiteQuer
0ac0: 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20 20 20  yBuilder();.    
0ad0: 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42      sqliteQueryB
0ae0: 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65 73  uilder.setTables
0af0: 28 45 4d 50 4c 4f 59 45 45 5f 54 41 42 4c 45 5f  (EMPLOYEE_TABLE_
0b00: 4e 41 4d 45 29 3b 0a 20 20 20 20 20 20 20 20 73  NAME);.        s
0b10: 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  qliteQueryBuilde
0b20: 72 2e 73 65 74 44 69 73 74 69 6e 63 74 28 74 72  r.setDistinct(tr
0b30: 75 65 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  ue);.        sql
0b40: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e  iteQueryBuilder.
0b50: 61 70 70 65 6e 64 57 68 65 72 65 28 22 61 67 65  appendWhere("age
0b60: 3e 33 32 22 29 3b 0a 20 20 20 20 20 20 20 20 73  >32");.        s
0b70: 71 6c 20 3d 20 73 71 6c 69 74 65 51 75 65 72 79  ql = sqliteQuery
0b80: 42 75 69 6c 64 65 72 2e 62 75 69 6c 64 51 75 65  Builder.buildQue
0b90: 72 79 28 6e 65 77 20 53 74 72 69 6e 67 5b 5d 20  ry(new String[] 
0ba0: 7b 20 22 61 67 65 22 2c 20 22 61 64 64 72 65 73  { "age", "addres
0bb0: 73 22 20 7d 2c 0a 20 20 20 20 20 20 20 20 20 20  s" },.          
0bc0: 20 20 20 20 20 20 6e 75 6c 6c 2c 20 6e 75 6c 6c        null, null
0bd0: 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75  , null, null, nu
0be0: 6c 6c 2c 20 6e 75 6c 6c 29 3b 0a 20 20 20 20 20  ll, null);.     
0bf0: 20 20 20 61 73 73 65 72 74 45 71 75 61 6c 73 28     assertEquals(
0c00: 45 4d 50 4c 4f 59 45 45 5f 54 41 42 4c 45 5f 4e  EMPLOYEE_TABLE_N
0c10: 41 4d 45 2c 20 73 71 6c 69 74 65 51 75 65 72 79  AME, sqliteQuery
0c20: 42 75 69 6c 64 65 72 2e 67 65 74 54 61 62 6c 65  Builder.getTable
0c30: 73 28 29 29 3b 0a 20 20 20 20 20 20 20 20 65 78  s());.        ex
0c40: 70 65 63 74 65 64 20 3d 20 22 53 45 4c 45 43 54  pected = "SELECT
0c50: 20 44 49 53 54 49 4e 43 54 20 61 67 65 2c 20 61   DISTINCT age, a
0c60: 64 64 72 65 73 73 20 46 52 4f 4d 20 22 20 2b 20  ddress FROM " + 
0c70: 45 4d 50 4c 4f 59 45 45 5f 54 41 42 4c 45 5f 4e  EMPLOYEE_TABLE_N
0c80: 41 4d 45 20 2b 20 22 20 57 48 45 52 45 20 28 61  AME + " WHERE (a
0c90: 67 65 3e 33 32 29 22 3b 0a 20 20 20 20 20 20 20  ge>32)";.       
0ca0: 20 61 73 73 65 72 74 45 71 75 61 6c 73 28 65 78   assertEquals(ex
0cb0: 70 65 63 74 65 64 2c 20 73 71 6c 29 3b 0a 0a 20  pected, sql);.. 
0cc0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 51 75 65         sqliteQue
0cd0: 72 79 42 75 69 6c 64 65 72 20 3d 20 6e 65 77 20  ryBuilder = new 
0ce0: 53 51 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64  SQLiteQueryBuild
0cf0: 65 72 28 29 3b 0a 20 20 20 20 20 20 20 20 73 71  er();.        sq
0d00: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
0d10: 2e 73 65 74 54 61 62 6c 65 73 28 45 4d 50 4c 4f  .setTables(EMPLO
0d20: 59 45 45 5f 54 41 42 4c 45 5f 4e 41 4d 45 29 3b  YEE_TABLE_NAME);
0d30: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 51  .        sqliteQ
0d40: 75 65 72 79 42 75 69 6c 64 65 72 2e 73 65 74 44  ueryBuilder.setD
0d50: 69 73 74 69 6e 63 74 28 74 72 75 65 29 3b 0a 20  istinct(true);. 
0d60: 20 20 20 20 20 20 20 73 71 6c 69 74 65 51 75 65         sqliteQue
0d70: 72 79 42 75 69 6c 64 65 72 2e 61 70 70 65 6e 64  ryBuilder.append
0d80: 57 68 65 72 65 45 73 63 61 70 65 53 74 72 69 6e  WhereEscapeStrin
0d90: 67 28 22 61 67 65 3e 33 32 22 29 3b 0a 20 20 20  g("age>32");.   
0da0: 20 20 20 20 20 73 71 6c 20 3d 20 73 71 6c 69 74       sql = sqlit
0db0: 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 62 75  eQueryBuilder.bu
0dc0: 69 6c 64 51 75 65 72 79 28 6e 65 77 20 53 74 72  ildQuery(new Str
0dd0: 69 6e 67 5b 5d 20 7b 20 22 61 67 65 22 2c 20 22  ing[] { "age", "
0de0: 61 64 64 72 65 73 73 22 20 7d 2c 0a 20 20 20 20  address" },.    
0df0: 20 20 20 20 20 20 20 20 20 20 20 20 6e 75 6c 6c              null
0e00: 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75  , null, null, nu
0e10: 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 29 3b  ll, null, null);
0e20: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 45  .        assertE
0e30: 71 75 61 6c 73 28 45 4d 50 4c 4f 59 45 45 5f 54  quals(EMPLOYEE_T
0e40: 41 42 4c 45 5f 4e 41 4d 45 2c 20 73 71 6c 69 74  ABLE_NAME, sqlit
0e50: 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 67 65  eQueryBuilder.ge
0e60: 74 54 61 62 6c 65 73 28 29 29 3b 0a 20 20 20 20  tTables());.    
0e70: 20 20 20 20 65 78 70 65 63 74 65 64 20 3d 20 22      expected = "
0e80: 53 45 4c 45 43 54 20 44 49 53 54 49 4e 43 54 20  SELECT DISTINCT 
0e90: 61 67 65 2c 20 61 64 64 72 65 73 73 20 46 52 4f  age, address FRO
0ea0: 4d 20 22 20 2b 20 45 4d 50 4c 4f 59 45 45 5f 54  M " + EMPLOYEE_T
0eb0: 41 42 4c 45 5f 4e 41 4d 45 0a 20 20 20 20 20 20  ABLE_NAME.      
0ec0: 20 20 20 20 20 20 20 20 20 20 2b 20 22 20 57 48            + " WH
0ed0: 45 52 45 20 28 27 61 67 65 3e 33 32 27 29 22 3b  ERE ('age>32')";
0ee0: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 45  .        assertE
0ef0: 71 75 61 6c 73 28 65 78 70 65 63 74 65 64 2c 20  quals(expected, 
0f00: 73 71 6c 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  sql);.    }..   
0f10: 20 70 75 62 6c 69 63 20 76 6f 69 64 20 74 65 73   public void tes
0f20: 74 53 65 74 50 72 6f 6a 65 63 74 69 6f 6e 4d 61  tSetProjectionMa
0f30: 70 28 29 20 7b 0a 20 20 20 20 20 20 20 20 53 74  p() {.        St
0f40: 72 69 6e 67 20 65 78 70 65 63 74 65 64 3b 0a 20  ring expected;. 
0f50: 20 20 20 20 20 20 20 4d 61 70 3c 53 74 72 69 6e         Map<Strin
0f60: 67 2c 20 53 74 72 69 6e 67 3e 20 70 72 6f 6a 65  g, String> proje
0f70: 63 74 4d 61 70 20 3d 20 6e 65 77 20 48 61 73 68  ctMap = new Hash
0f80: 4d 61 70 3c 53 74 72 69 6e 67 2c 20 53 74 72 69  Map<String, Stri
0f90: 6e 67 3e 28 29 3b 0a 20 20 20 20 20 20 20 20 70  ng>();.        p
0fa0: 72 6f 6a 65 63 74 4d 61 70 2e 70 75 74 28 22 45  rojectMap.put("E
0fb0: 6d 70 6c 6f 79 65 65 4e 61 6d 65 22 2c 20 22 6e  mployeeName", "n
0fc0: 61 6d 65 22 29 3b 0a 20 20 20 20 20 20 20 20 70  ame");.        p
0fd0: 72 6f 6a 65 63 74 4d 61 70 2e 70 75 74 28 22 45  rojectMap.put("E
0fe0: 6d 70 6c 6f 79 65 65 41 67 65 22 2c 20 22 61 67  mployeeAge", "ag
0ff0: 65 22 29 3b 0a 20 20 20 20 20 20 20 20 70 72 6f  e");.        pro
1000: 6a 65 63 74 4d 61 70 2e 70 75 74 28 22 45 6d 70  jectMap.put("Emp
1010: 6c 6f 79 65 65 41 64 64 72 65 73 73 22 2c 20 22  loyeeAddress", "
1020: 61 64 64 72 65 73 73 22 29 3b 0a 20 20 20 20 20  address");.     
1030: 20 20 20 53 51 4c 69 74 65 51 75 65 72 79 42 75     SQLiteQueryBu
1040: 69 6c 64 65 72 20 73 71 6c 69 74 65 51 75 65 72  ilder sqliteQuer
1050: 79 42 75 69 6c 64 65 72 20 3d 20 6e 65 77 20 53  yBuilder = new S
1060: 51 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  QLiteQueryBuilde
1070: 72 28 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  r();.        sql
1080: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e  iteQueryBuilder.
1090: 73 65 74 54 61 62 6c 65 73 28 54 45 53 54 5f 54  setTables(TEST_T
10a0: 41 42 4c 45 5f 4e 41 4d 45 29 3b 0a 20 20 20 20  ABLE_NAME);.    
10b0: 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42      sqliteQueryB
10c0: 75 69 6c 64 65 72 2e 73 65 74 44 69 73 74 69 6e  uilder.setDistin
10d0: 63 74 28 66 61 6c 73 65 29 3b 0a 20 20 20 20 20  ct(false);.     
10e0: 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42 75     sqliteQueryBu
10f0: 69 6c 64 65 72 2e 73 65 74 50 72 6f 6a 65 63 74  ilder.setProject
1100: 69 6f 6e 4d 61 70 28 70 72 6f 6a 65 63 74 4d 61  ionMap(projectMa
1110: 70 29 3b 0a 20 20 20 20 20 20 20 20 53 74 72 69  p);.        Stri
1120: 6e 67 20 73 71 6c 20 3d 20 73 71 6c 69 74 65 51  ng sql = sqliteQ
1130: 75 65 72 79 42 75 69 6c 64 65 72 2e 62 75 69 6c  ueryBuilder.buil
1140: 64 51 75 65 72 79 28 6e 65 77 20 53 74 72 69 6e  dQuery(new Strin
1150: 67 5b 5d 20 7b 20 22 45 6d 70 6c 6f 79 65 65 4e  g[] { "EmployeeN
1160: 61 6d 65 22 2c 20 22 45 6d 70 6c 6f 79 65 65 41  ame", "EmployeeA
1170: 67 65 22 20 7d 2c 0a 20 20 20 20 20 20 20 20 20  ge" },.         
1180: 20 20 20 20 20 20 20 6e 75 6c 6c 2c 20 6e 75 6c         null, nul
1190: 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e  l, null, null, n
11a0: 75 6c 6c 2c 20 6e 75 6c 6c 29 3b 0a 20 20 20 20  ull, null);.    
11b0: 20 20 20 20 65 78 70 65 63 74 65 64 20 3d 20 22      expected = "
11c0: 53 45 4c 45 43 54 20 6e 61 6d 65 2c 20 61 67 65  SELECT name, age
11d0: 20 46 52 4f 4d 20 22 20 2b 20 54 45 53 54 5f 54   FROM " + TEST_T
11e0: 41 42 4c 45 5f 4e 41 4d 45 3b 0a 20 20 20 20 20  ABLE_NAME;.     
11f0: 20 20 20 61 73 73 65 72 74 45 71 75 61 6c 73 28     assertEquals(
1200: 65 78 70 65 63 74 65 64 2c 20 73 71 6c 29 3b 0a  expected, sql);.
1210: 0a 20 20 20 20 20 20 20 20 73 71 6c 20 3d 20 73  .        sql = s
1220: 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  qliteQueryBuilde
1230: 72 2e 62 75 69 6c 64 51 75 65 72 79 28 6e 75 6c  r.buildQuery(nul
1240: 6c 2c 20 2f 2f 20 70 72 6f 6a 65 63 74 69 6f 6e  l, // projection
1250: 49 6e 20 69 73 20 6e 75 6c 6c 0a 20 20 20 20 20  In is null.     
1260: 20 20 20 20 20 20 20 20 20 20 20 6e 75 6c 6c 2c             null,
1270: 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c   null, null, nul
1280: 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 29 3b 0a  l, null, null);.
1290: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 54 72          assertTr
12a0: 75 65 28 73 71 6c 2e 6d 61 74 63 68 65 73 28 22  ue(sql.matches("
12b0: 53 45 4c 45 43 54 20 28 61 67 65 7c 6e 61 6d 65  SELECT (age|name
12c0: 7c 61 64 64 72 65 73 73 29 2c 20 28 61 67 65 7c  |address), (age|
12d0: 6e 61 6d 65 7c 61 64 64 72 65 73 73 29 2c 20 28  name|address), (
12e0: 61 67 65 7c 6e 61 6d 65 7c 61 64 64 72 65 73 73  age|name|address
12f0: 29 20 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) ".            
1300: 20 20 20 20 2b 20 22 46 52 4f 4d 20 22 20 2b 20      + "FROM " + 
1310: 54 45 53 54 5f 54 41 42 4c 45 5f 4e 41 4d 45 29  TEST_TABLE_NAME)
1320: 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  );.        asser
1330: 74 54 72 75 65 28 73 71 6c 2e 63 6f 6e 74 61 69  tTrue(sql.contai
1340: 6e 73 28 22 61 67 65 22 29 29 3b 0a 20 20 20 20  ns("age"));.    
1350: 20 20 20 20 61 73 73 65 72 74 54 72 75 65 28 73      assertTrue(s
1360: 71 6c 2e 63 6f 6e 74 61 69 6e 73 28 22 6e 61 6d  ql.contains("nam
1370: 65 22 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73  e"));.        as
1380: 73 65 72 74 54 72 75 65 28 73 71 6c 2e 63 6f 6e  sertTrue(sql.con
1390: 74 61 69 6e 73 28 22 61 64 64 72 65 73 73 22 29  tains("address")
13a0: 29 3b 0a 0a 20 20 20 20 20 20 20 20 73 71 6c 69  );..        sqli
13b0: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 73  teQueryBuilder.s
13c0: 65 74 50 72 6f 6a 65 63 74 69 6f 6e 4d 61 70 28  etProjectionMap(
13d0: 6e 75 6c 6c 29 3b 0a 20 20 20 20 20 20 20 20 73  null);.        s
13e0: 71 6c 20 3d 20 73 71 6c 69 74 65 51 75 65 72 79  ql = sqliteQuery
13f0: 42 75 69 6c 64 65 72 2e 62 75 69 6c 64 51 75 65  Builder.buildQue
1400: 72 79 28 6e 65 77 20 53 74 72 69 6e 67 5b 5d 20  ry(new String[] 
1410: 7b 20 22 6e 61 6d 65 22 2c 20 22 61 64 64 72 65  { "name", "addre
1420: 73 73 22 20 7d 2c 0a 20 20 20 20 20 20 20 20 20  ss" },.         
1430: 20 20 20 20 20 20 20 6e 75 6c 6c 2c 20 6e 75 6c         null, nul
1440: 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e  l, null, null, n
1450: 75 6c 6c 2c 20 6e 75 6c 6c 29 3b 0a 20 20 20 20  ull, null);.    
1460: 20 20 20 20 61 73 73 65 72 74 54 72 75 65 28 73      assertTrue(s
1470: 71 6c 2e 6d 61 74 63 68 65 73 28 22 53 45 4c 45  ql.matches("SELE
1480: 43 54 20 28 6e 61 6d 65 7c 61 64 64 72 65 73 73  CT (name|address
1490: 29 2c 20 28 6e 61 6d 65 7c 61 64 64 72 65 73 73  ), (name|address
14a0: 29 20 22 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) ".            
14b0: 20 20 20 20 2b 20 22 46 52 4f 4d 20 22 20 2b 20      + "FROM " + 
14c0: 54 45 53 54 5f 54 41 42 4c 45 5f 4e 41 4d 45 29  TEST_TABLE_NAME)
14d0: 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  );.        asser
14e0: 74 54 72 75 65 28 73 71 6c 2e 63 6f 6e 74 61 69  tTrue(sql.contai
14f0: 6e 73 28 22 6e 61 6d 65 22 29 29 3b 0a 20 20 20  ns("name"));.   
1500: 20 20 20 20 20 61 73 73 65 72 74 54 72 75 65 28       assertTrue(
1510: 73 71 6c 2e 63 6f 6e 74 61 69 6e 73 28 22 61 64  sql.contains("ad
1520: 64 72 65 73 73 22 29 29 3b 0a 20 20 20 20 7d 0a  dress"));.    }.
1530: 0a 20 20 20 20 70 75 62 6c 69 63 20 76 6f 69 64  .    public void
1540: 20 74 65 73 74 53 65 74 43 75 72 73 6f 72 46 61   testSetCursorFa
1550: 63 74 6f 72 79 28 29 20 7b 0a 20 20 20 20 20 20  ctory() {.      
1560: 20 20 6d 44 61 74 61 62 61 73 65 2e 65 78 65 63    mDatabase.exec
1570: 53 51 4c 28 22 43 52 45 41 54 45 20 54 41 42 4c  SQL("CREATE TABL
1580: 45 20 74 65 73 74 20 28 5f 69 64 20 49 4e 54 45  E test (_id INTE
1590: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c  GER PRIMARY KEY,
15a0: 20 22 20 2b 0a 20 20 20 20 20 20 20 20 20 20 20   " +.           
15b0: 20 20 20 20 20 22 6e 61 6d 65 20 54 45 58 54 2c       "name TEXT,
15c0: 20 61 67 65 20 49 4e 54 45 47 45 52 2c 20 61 64   age INTEGER, ad
15d0: 64 72 65 73 73 20 54 45 58 54 29 3b 22 29 3b 0a  dress TEXT);");.
15e0: 20 20 20 20 20 20 20 20 6d 44 61 74 61 62 61 73          mDatabas
15f0: 65 2e 65 78 65 63 53 51 4c 28 22 49 4e 53 45 52  e.execSQL("INSER
1600: 54 20 49 4e 54 4f 20 74 65 73 74 20 28 6e 61 6d  T INTO test (nam
1610: 65 2c 20 61 67 65 2c 20 61 64 64 72 65 73 73 29  e, age, address)
1620: 20 56 41 4c 55 45 53 20 28 27 4d 69 6b 65 27 2c   VALUES ('Mike',
1630: 20 27 32 30 27 2c 20 27 4c 41 27 29 3b 22 29 3b   '20', 'LA');");
1640: 0a 20 20 20 20 20 20 20 20 6d 44 61 74 61 62 61  .        mDataba
1650: 73 65 2e 65 78 65 63 53 51 4c 28 22 49 4e 53 45  se.execSQL("INSE
1660: 52 54 20 49 4e 54 4f 20 74 65 73 74 20 28 6e 61  RT INTO test (na
1670: 6d 65 2c 20 61 67 65 2c 20 61 64 64 72 65 73 73  me, age, address
1680: 29 20 56 41 4c 55 45 53 20 28 27 6a 61 63 6b 27  ) VALUES ('jack'
1690: 2c 20 27 34 30 27 2c 20 27 4c 41 27 29 3b 22 29  , '40', 'LA');")
16a0: 3b 0a 0a 20 20 20 20 20 20 20 20 53 51 4c 69 74  ;..        SQLit
16b0: 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 73 71  eQueryBuilder sq
16c0: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
16d0: 20 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75 65   = new SQLiteQue
16e0: 72 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20 20  ryBuilder();.   
16f0: 20 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79       sqliteQuery
1700: 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65  Builder.setTable
1710: 73 28 54 45 53 54 5f 54 41 42 4c 45 5f 4e 41 4d  s(TEST_TABLE_NAM
1720: 45 29 3b 0a 20 20 20 20 20 20 20 20 43 75 72 73  E);.        Curs
1730: 6f 72 20 63 75 72 73 6f 72 20 3d 20 73 71 6c 69  or cursor = sqli
1740: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 71  teQueryBuilder.q
1750: 75 65 72 79 28 6d 44 61 74 61 62 61 73 65 2c 20  uery(mDatabase, 
1760: 6e 65 77 20 53 74 72 69 6e 67 5b 5d 20 7b 20 22  new String[] { "
1770: 6e 61 6d 65 22 2c 20 22 61 67 65 22 20 7d 2c 0a  name", "age" },.
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1790: 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c  null, null, null
17a0: 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 29 3b 0a 20  , null, null);. 
17b0: 20 20 20 20 20 20 20 61 73 73 65 72 74 4e 6f 74         assertNot
17c0: 4e 75 6c 6c 28 63 75 72 73 6f 72 29 3b 0a 20 20  Null(cursor);.  
17d0: 20 20 20 20 20 20 61 73 73 65 72 74 54 72 75 65        assertTrue
17e0: 28 63 75 72 73 6f 72 20 69 6e 73 74 61 6e 63 65  (cursor instance
17f0: 6f 66 20 53 51 4c 69 74 65 43 75 72 73 6f 72 29  of SQLiteCursor)
1800: 3b 0a 0a 20 20 20 20 20 20 20 20 53 51 4c 69 74  ;..        SQLit
1810: 65 44 61 74 61 62 61 73 65 2e 43 75 72 73 6f 72  eDatabase.Cursor
1820: 46 61 63 74 6f 72 79 20 66 61 63 74 6f 72 79 20  Factory factory 
1830: 3d 20 6e 65 77 20 53 51 4c 69 74 65 44 61 74 61  = new SQLiteData
1840: 62 61 73 65 2e 43 75 72 73 6f 72 46 61 63 74 6f  base.CursorFacto
1850: 72 79 28 29 20 7b 0a 20 20 20 20 20 20 20 20 20  ry() {.         
1860: 20 20 20 70 75 62 6c 69 63 20 43 75 72 73 6f 72     public Cursor
1870: 20 6e 65 77 43 75 72 73 6f 72 28 53 51 4c 69 74   newCursor(SQLit
1880: 65 44 61 74 61 62 61 73 65 20 64 62 2c 20 53 51  eDatabase db, SQ
1890: 4c 69 74 65 43 75 72 73 6f 72 44 72 69 76 65 72  LiteCursorDriver
18a0: 20 6d 61 73 74 65 72 51 75 65 72 79 2c 0a 20 20   masterQuery,.  
18b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c0: 20 20 53 74 72 69 6e 67 20 65 64 69 74 54 61 62    String editTab
18d0: 6c 65 2c 20 53 51 4c 69 74 65 51 75 65 72 79 20  le, SQLiteQuery 
18e0: 71 75 65 72 79 29 20 7b 0a 20 20 20 20 20 20 20  query) {.       
18f0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
1900: 6e 65 77 20 4d 6f 63 6b 43 75 72 73 6f 72 28 64  new MockCursor(d
1910: 62 2c 20 6d 61 73 74 65 72 51 75 65 72 79 2c 20  b, masterQuery, 
1920: 65 64 69 74 54 61 62 6c 65 2c 20 71 75 65 72 79  editTable, query
1930: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
1940: 0a 20 20 20 20 20 20 20 20 7d 3b 0a 0a 20 20 20  .        };..   
1950: 20 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79       sqliteQuery
1960: 42 75 69 6c 64 65 72 2e 73 65 74 43 75 72 73 6f  Builder.setCurso
1970: 72 46 61 63 74 6f 72 79 28 66 61 63 74 6f 72 79  rFactory(factory
1980: 29 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73 6f  );.        curso
1990: 72 20 3d 20 73 71 6c 69 74 65 51 75 65 72 79 42  r = sqliteQueryB
19a0: 75 69 6c 64 65 72 2e 71 75 65 72 79 28 6d 44 61  uilder.query(mDa
19b0: 74 61 62 61 73 65 2c 20 6e 65 77 20 53 74 72 69  tabase, new Stri
19c0: 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22 2c 20 22  ng[] { "name", "
19d0: 61 67 65 22 20 7d 2c 0a 20 20 20 20 20 20 20 20  age" },.        
19e0: 20 20 20 20 20 20 20 20 6e 75 6c 6c 2c 20 6e 75          null, nu
19f0: 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20  ll, null, null, 
1a00: 6e 75 6c 6c 29 3b 0a 20 20 20 20 20 20 20 20 61  null);.        a
1a10: 73 73 65 72 74 4e 6f 74 4e 75 6c 6c 28 63 75 72  ssertNotNull(cur
1a20: 73 6f 72 29 3b 0a 20 20 20 20 20 20 20 20 61 73  sor);.        as
1a30: 73 65 72 74 54 72 75 65 28 63 75 72 73 6f 72 20  sertTrue(cursor 
1a40: 69 6e 73 74 61 6e 63 65 6f 66 20 4d 6f 63 6b 43  instanceof MockC
1a50: 75 72 73 6f 72 29 3b 0a 20 20 20 20 7d 0a 0a 20  ursor);.    }.. 
1a60: 20 20 20 70 72 69 76 61 74 65 20 73 74 61 74 69     private stati
1a70: 63 20 63 6c 61 73 73 20 4d 6f 63 6b 43 75 72 73  c class MockCurs
1a80: 6f 72 20 65 78 74 65 6e 64 73 20 53 51 4c 69 74  or extends SQLit
1a90: 65 43 75 72 73 6f 72 20 7b 0a 20 20 20 20 20 20  eCursor {.      
1aa0: 20 20 70 75 62 6c 69 63 20 4d 6f 63 6b 43 75 72    public MockCur
1ab0: 73 6f 72 28 53 51 4c 69 74 65 44 61 74 61 62 61  sor(SQLiteDataba
1ac0: 73 65 20 64 62 2c 20 53 51 4c 69 74 65 43 75 72  se db, SQLiteCur
1ad0: 73 6f 72 44 72 69 76 65 72 20 64 72 69 76 65 72  sorDriver driver
1ae0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
1af0: 20 20 53 74 72 69 6e 67 20 65 64 69 74 54 61 62    String editTab
1b00: 6c 65 2c 20 53 51 4c 69 74 65 51 75 65 72 79 20  le, SQLiteQuery 
1b10: 71 75 65 72 79 29 20 7b 0a 20 20 20 20 20 20 20  query) {.       
1b20: 20 20 20 20 20 73 75 70 65 72 28 64 62 2c 20 64       super(db, d
1b30: 72 69 76 65 72 2c 20 65 64 69 74 54 61 62 6c 65  river, editTable
1b40: 2c 20 71 75 65 72 79 29 3b 0a 20 20 20 20 20 20  , query);.      
1b50: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70    }.    }..    p
1b60: 75 62 6c 69 63 20 76 6f 69 64 20 74 65 73 74 42  ublic void testB
1b70: 75 69 6c 64 51 75 65 72 79 53 74 72 69 6e 67 28  uildQueryString(
1b80: 29 20 7b 0a 20 20 20 20 20 20 20 20 53 74 72 69  ) {.        Stri
1b90: 6e 67 20 65 78 70 65 63 74 65 64 3b 0a 20 20 20  ng expected;.   
1ba0: 20 20 20 20 20 66 69 6e 61 6c 20 53 74 72 69 6e       final Strin
1bb0: 67 5b 5d 20 44 45 46 41 55 4c 54 5f 54 45 53 54  g[] DEFAULT_TEST
1bc0: 5f 50 52 4f 4a 45 43 54 49 4f 4e 20 3d 20 6e 65  _PROJECTION = ne
1bd0: 77 20 53 74 72 69 6e 67 20 5b 5d 20 7b 20 22 6e  w String [] { "n
1be0: 61 6d 65 22 2c 20 22 61 67 65 22 2c 20 22 73 75  ame", "age", "su
1bf0: 6d 28 73 61 6c 61 72 79 29 22 20 7d 3b 0a 20 20  m(salary)" };.  
1c00: 20 20 20 20 20 20 66 69 6e 61 6c 20 53 74 72 69        final Stri
1c10: 6e 67 20 44 45 46 41 55 4c 54 5f 54 45 53 54 5f  ng DEFAULT_TEST_
1c20: 57 48 45 52 45 20 3d 20 22 61 67 65 20 3e 20 32  WHERE = "age > 2
1c30: 35 22 3b 0a 20 20 20 20 20 20 20 20 66 69 6e 61  5";.        fina
1c40: 6c 20 53 74 72 69 6e 67 20 44 45 46 41 55 4c 54  l String DEFAULT
1c50: 5f 48 41 56 49 4e 47 20 3d 20 22 73 75 6d 28 73  _HAVING = "sum(s
1c60: 61 6c 61 72 79 29 20 3e 20 33 30 30 30 22 3b 0a  alary) > 3000";.
1c70: 0a 20 20 20 20 20 20 20 20 53 74 72 69 6e 67 20  .        String 
1c80: 73 71 6c 20 3d 20 53 51 4c 69 74 65 51 75 65 72  sql = SQLiteQuer
1c90: 79 42 75 69 6c 64 65 72 2e 62 75 69 6c 64 51 75  yBuilder.buildQu
1ca0: 65 72 79 53 74 72 69 6e 67 28 66 61 6c 73 65 2c  eryString(false,
1cb0: 20 22 45 6d 70 6c 6f 79 65 65 22 2c 0a 20 20 20   "Employee",.   
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 44 45 46               DEF
1cd0: 41 55 4c 54 5f 54 45 53 54 5f 50 52 4f 4a 45 43  AULT_TEST_PROJEC
1ce0: 54 49 4f 4e 2c 0a 20 20 20 20 20 20 20 20 20 20  TION,.          
1cf0: 20 20 20 20 20 20 44 45 46 41 55 4c 54 5f 54 45        DEFAULT_TE
1d00: 53 54 5f 57 48 45 52 45 2c 20 22 6e 61 6d 65 22  ST_WHERE, "name"
1d10: 2c 20 44 45 46 41 55 4c 54 5f 48 41 56 49 4e 47  , DEFAULT_HAVING
1d20: 2c 20 22 6e 61 6d 65 22 2c 20 22 31 30 30 22 29  , "name", "100")
1d30: 3b 0a 0a 20 20 20 20 20 20 20 20 65 78 70 65 63  ;..        expec
1d40: 74 65 64 20 3d 20 22 53 45 4c 45 43 54 20 6e 61  ted = "SELECT na
1d50: 6d 65 2c 20 61 67 65 2c 20 73 75 6d 28 73 61 6c  me, age, sum(sal
1d60: 61 72 79 29 20 46 52 4f 4d 20 45 6d 70 6c 6f 79  ary) FROM Employ
1d70: 65 65 20 57 48 45 52 45 20 22 20 2b 20 44 45 46  ee WHERE " + DEF
1d80: 41 55 4c 54 5f 54 45 53 54 5f 57 48 45 52 45 20  AULT_TEST_WHERE 
1d90: 2b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  +.              
1da0: 20 20 22 20 47 52 4f 55 50 20 42 59 20 6e 61 6d    " GROUP BY nam
1db0: 65 20 22 20 2b 0a 20 20 20 20 20 20 20 20 20 20  e " +.          
1dc0: 20 20 20 20 20 20 22 48 41 56 49 4e 47 20 22 20        "HAVING " 
1dd0: 2b 20 44 45 46 41 55 4c 54 5f 48 41 56 49 4e 47  + DEFAULT_HAVING
1de0: 20 2b 20 22 20 22 20 2b 0a 20 20 20 20 20 20 20   + " " +.       
1df0: 20 20 20 20 20 20 20 20 20 22 4f 52 44 45 52 20           "ORDER 
1e00: 42 59 20 6e 61 6d 65 20 22 20 2b 0a 20 20 20 20  BY name " +.    
1e10: 20 20 20 20 20 20 20 20 20 20 20 20 22 4c 49 4d              "LIM
1e20: 49 54 20 31 30 30 22 3b 0a 20 20 20 20 20 20 20  IT 100";.       
1e30: 20 61 73 73 65 72 74 45 71 75 61 6c 73 28 65 78   assertEquals(ex
1e40: 70 65 63 74 65 64 2c 20 73 71 6c 29 3b 0a 20 20  pected, sql);.  
1e50: 20 20 7d 0a 0a 20 20 20 20 70 75 62 6c 69 63 20    }..    public 
1e60: 76 6f 69 64 20 74 65 73 74 42 75 69 6c 64 51 75  void testBuildQu
1e70: 65 72 79 28 29 20 7b 0a 20 20 20 20 20 20 20 20  ery() {.        
1e80: 66 69 6e 61 6c 20 53 74 72 69 6e 67 5b 5d 20 44  final String[] D
1e90: 45 46 41 55 4c 54 5f 54 45 53 54 5f 50 52 4f 4a  EFAULT_TEST_PROJ
1ea0: 45 43 54 49 4f 4e 20 3d 20 6e 65 77 20 53 74 72  ECTION = new Str
1eb0: 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22 2c 20  ing[] { "name", 
1ec0: 22 73 75 6d 28 73 61 6c 61 72 79 29 22 20 7d 3b  "sum(salary)" };
1ed0: 0a 20 20 20 20 20 20 20 20 66 69 6e 61 6c 20 53  .        final S
1ee0: 74 72 69 6e 67 20 44 45 46 41 55 4c 54 5f 54 45  tring DEFAULT_TE
1ef0: 53 54 5f 57 48 45 52 45 20 3d 20 22 61 67 65 20  ST_WHERE = "age 
1f00: 3e 20 32 35 22 3b 0a 20 20 20 20 20 20 20 20 66  > 25";.        f
1f10: 69 6e 61 6c 20 53 74 72 69 6e 67 20 44 45 46 41  inal String DEFA
1f20: 55 4c 54 5f 48 41 56 49 4e 47 20 3d 20 22 73 75  ULT_HAVING = "su
1f30: 6d 28 73 61 6c 61 72 79 29 20 3e 20 32 30 30 30  m(salary) > 2000
1f40: 22 3b 0a 0a 20 20 20 20 20 20 20 20 53 51 4c 69  ";..        SQLi
1f50: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 73  teQueryBuilder s
1f60: 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  qliteQueryBuilde
1f70: 72 20 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75  r = new SQLiteQu
1f80: 65 72 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20  eryBuilder();.  
1f90: 20 20 20 20 20 20 73 71 6c 69 74 65 51 75 65 72        sqliteQuer
1fa0: 79 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c  yBuilder.setTabl
1fb0: 65 73 28 54 45 53 54 5f 54 41 42 4c 45 5f 4e 41  es(TEST_TABLE_NA
1fc0: 4d 45 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  ME);.        sql
1fd0: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e  iteQueryBuilder.
1fe0: 73 65 74 44 69 73 74 69 6e 63 74 28 66 61 6c 73  setDistinct(fals
1ff0: 65 29 3b 0a 20 20 20 20 20 20 20 20 53 74 72 69  e);.        Stri
2000: 6e 67 20 73 71 6c 20 3d 20 73 71 6c 69 74 65 51  ng sql = sqliteQ
2010: 75 65 72 79 42 75 69 6c 64 65 72 2e 62 75 69 6c  ueryBuilder.buil
2020: 64 51 75 65 72 79 28 44 45 46 41 55 4c 54 5f 54  dQuery(DEFAULT_T
2030: 45 53 54 5f 50 52 4f 4a 45 43 54 49 4f 4e 2c 0a  EST_PROJECTION,.
2040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2050: 44 45 46 41 55 4c 54 5f 54 45 53 54 5f 57 48 45  DEFAULT_TEST_WHE
2060: 52 45 2c 20 6e 75 6c 6c 2c 20 22 6e 61 6d 65 22  RE, null, "name"
2070: 2c 20 44 45 46 41 55 4c 54 5f 48 41 56 49 4e 47  , DEFAULT_HAVING
2080: 2c 20 22 6e 61 6d 65 22 2c 20 22 32 22 29 3b 0a  , "name", "2");.
2090: 20 20 20 20 20 20 20 20 53 74 72 69 6e 67 20 65          String e
20a0: 78 70 65 63 74 65 64 20 3d 20 22 53 45 4c 45 43  xpected = "SELEC
20b0: 54 20 6e 61 6d 65 2c 20 73 75 6d 28 73 61 6c 61  T name, sum(sala
20c0: 72 79 29 20 46 52 4f 4d 20 22 20 2b 20 54 45 53  ry) FROM " + TES
20d0: 54 5f 54 41 42 4c 45 5f 4e 41 4d 45 0a 20 20 20  T_TABLE_NAME.   
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2b 20 22               + "
20f0: 20 57 48 45 52 45 20 28 22 20 2b 20 44 45 46 41   WHERE (" + DEFA
2100: 55 4c 54 5f 54 45 53 54 5f 57 48 45 52 45 20 2b  ULT_TEST_WHERE +
2110: 20 22 29 20 22 20 2b 0a 20 20 20 20 20 20 20 20   ") " +.        
2120: 20 20 20 20 20 20 20 20 22 47 52 4f 55 50 20 42          "GROUP B
2130: 59 20 6e 61 6d 65 20 48 41 56 49 4e 47 20 22 20  Y name HAVING " 
2140: 2b 20 44 45 46 41 55 4c 54 5f 48 41 56 49 4e 47  + DEFAULT_HAVING
2150: 20 2b 20 22 20 4f 52 44 45 52 20 42 59 20 6e 61   + " ORDER BY na
2160: 6d 65 20 4c 49 4d 49 54 20 32 22 3b 0a 20 20 20  me LIMIT 2";.   
2170: 20 20 20 20 20 61 73 73 65 72 74 45 71 75 61 6c       assertEqual
2180: 73 28 65 78 70 65 63 74 65 64 2c 20 73 71 6c 29  s(expected, sql)
2190: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 75 62  ;.    }..    pub
21a0: 6c 69 63 20 76 6f 69 64 20 74 65 73 74 41 70 70  lic void testApp
21b0: 65 6e 64 43 6f 6c 75 6d 6e 73 28 29 20 7b 0a 20  endColumns() {. 
21c0: 20 20 20 20 20 20 20 53 74 72 69 6e 67 42 75 69         StringBui
21d0: 6c 64 65 72 20 73 62 20 3d 20 6e 65 77 20 53 74  lder sb = new St
21e0: 72 69 6e 67 42 75 69 6c 64 65 72 28 29 3b 0a 20  ringBuilder();. 
21f0: 20 20 20 20 20 20 20 53 74 72 69 6e 67 5b 5d 20         String[] 
2200: 63 6f 6c 75 6d 6e 73 20 3d 20 6e 65 77 20 53 74  columns = new St
2210: 72 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22 2c  ring[] { "name",
2220: 20 22 61 67 65 22 20 7d 3b 0a 0a 20 20 20 20 20   "age" };..     
2230: 20 20 20 61 73 73 65 72 74 45 71 75 61 6c 73 28     assertEquals(
2240: 22 22 2c 20 73 62 2e 74 6f 53 74 72 69 6e 67 28  "", sb.toString(
2250: 29 29 3b 0a 20 20 20 20 20 20 20 20 53 51 4c 69  ));.        SQLi
2260: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 2e 61  teQueryBuilder.a
2270: 70 70 65 6e 64 43 6f 6c 75 6d 6e 73 28 73 62 2c  ppendColumns(sb,
2280: 20 63 6f 6c 75 6d 6e 73 29 3b 0a 20 20 20 20 20   columns);.     
2290: 20 20 20 61 73 73 65 72 74 45 71 75 61 6c 73 28     assertEquals(
22a0: 22 6e 61 6d 65 2c 20 61 67 65 20 22 2c 20 73 62  "name, age ", sb
22b0: 2e 74 6f 53 74 72 69 6e 67 28 29 29 3b 0a 20 20  .toString());.  
22c0: 20 20 7d 0a 0a 20 20 20 20 70 75 62 6c 69 63 20    }..    public 
22d0: 76 6f 69 64 20 74 65 73 74 51 75 65 72 79 28 29  void testQuery()
22e0: 20 7b 0a 20 20 20 20 20 20 20 20 63 72 65 61 74   {.        creat
22f0: 65 45 6d 70 6c 6f 79 65 65 54 61 62 6c 65 28 29  eEmployeeTable()
2300: 3b 0a 0a 20 20 20 20 20 20 20 20 53 51 4c 69 74  ;..        SQLit
2310: 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 73 71  eQueryBuilder sq
2320: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
2330: 20 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75 65   = new SQLiteQue
2340: 72 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20 20  ryBuilder();.   
2350: 20 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79       sqliteQuery
2360: 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65  Builder.setTable
2370: 73 28 22 45 6d 70 6c 6f 79 65 65 22 29 3b 0a 20  s("Employee");. 
2380: 20 20 20 20 20 20 20 43 75 72 73 6f 72 20 63 75         Cursor cu
2390: 72 73 6f 72 20 3d 20 73 71 6c 69 74 65 51 75 65  rsor = sqliteQue
23a0: 72 79 42 75 69 6c 64 65 72 2e 71 75 65 72 79 28  ryBuilder.query(
23b0: 6d 44 61 74 61 62 61 73 65 2c 0a 20 20 20 20 20  mDatabase,.     
23c0: 20 20 20 20 20 20 20 20 20 20 20 6e 65 77 20 53             new S
23d0: 74 72 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22  tring[] { "name"
23e0: 2c 20 22 73 75 6d 28 73 61 6c 61 72 79 29 22 20  , "sum(salary)" 
23f0: 7d 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 0a 20  }, null, null,. 
2400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
2410: 6e 61 6d 65 22 2c 20 22 73 75 6d 28 73 61 6c 61  name", "sum(sala
2420: 72 79 29 3e 31 30 30 30 22 2c 20 22 6e 61 6d 65  ry)>1000", "name
2430: 22 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ");.        asse
2440: 72 74 4e 6f 74 4e 75 6c 6c 28 63 75 72 73 6f 72  rtNotNull(cursor
2450: 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  );.        asser
2460: 74 45 71 75 61 6c 73 28 33 2c 20 63 75 72 73 6f  tEquals(3, curso
2470: 72 2e 67 65 74 43 6f 75 6e 74 28 29 29 3b 0a 0a  r.getCount());..
2480: 20 20 20 20 20 20 20 20 66 69 6e 61 6c 20 69 6e          final in
2490: 74 20 43 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e  t COLUMN_NAME_IN
24a0: 44 45 58 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  DEX = 0;.       
24b0: 20 66 69 6e 61 6c 20 69 6e 74 20 43 4f 4c 55 4d   final int COLUM
24c0: 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58 20 3d  N_SALARY_INDEX =
24d0: 20 31 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73   1;.        curs
24e0: 6f 72 2e 6d 6f 76 65 54 6f 46 69 72 73 74 28 29  or.moveToFirst()
24f0: 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
2500: 45 71 75 61 6c 73 28 22 4a 69 6d 22 2c 20 63 75  Equals("Jim", cu
2510: 72 73 6f 72 2e 67 65 74 53 74 72 69 6e 67 28 43  rsor.getString(C
2520: 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e 44 45 58  OLUMN_NAME_INDEX
2530: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ));.        asse
2540: 72 74 45 71 75 61 6c 73 28 34 35 30 30 2c 20 63  rtEquals(4500, c
2550: 75 72 73 6f 72 2e 67 65 74 49 6e 74 28 43 4f 4c  ursor.getInt(COL
2560: 55 4d 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58  UMN_SALARY_INDEX
2570: 29 29 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73  ));.        curs
2580: 6f 72 2e 6d 6f 76 65 54 6f 4e 65 78 74 28 29 3b  or.moveToNext();
2590: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 45  .        assertE
25a0: 71 75 61 6c 73 28 22 4d 69 6b 65 22 2c 20 63 75  quals("Mike", cu
25b0: 72 73 6f 72 2e 67 65 74 53 74 72 69 6e 67 28 43  rsor.getString(C
25c0: 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e 44 45 58  OLUMN_NAME_INDEX
25d0: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ));.        asse
25e0: 72 74 45 71 75 61 6c 73 28 34 30 30 30 2c 20 63  rtEquals(4000, c
25f0: 75 72 73 6f 72 2e 67 65 74 49 6e 74 28 43 4f 4c  ursor.getInt(COL
2600: 55 4d 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58  UMN_SALARY_INDEX
2610: 29 29 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73  ));.        curs
2620: 6f 72 2e 6d 6f 76 65 54 6f 4e 65 78 74 28 29 3b  or.moveToNext();
2630: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 45  .        assertE
2640: 71 75 61 6c 73 28 22 6a 61 63 6b 22 2c 20 63 75  quals("jack", cu
2650: 72 73 6f 72 2e 67 65 74 53 74 72 69 6e 67 28 43  rsor.getString(C
2660: 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e 44 45 58  OLUMN_NAME_INDEX
2670: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ));.        asse
2680: 72 74 45 71 75 61 6c 73 28 33 35 30 30 2c 20 63  rtEquals(3500, c
2690: 75 72 73 6f 72 2e 67 65 74 49 6e 74 28 43 4f 4c  ursor.getInt(COL
26a0: 55 4d 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58  UMN_SALARY_INDEX
26b0: 29 29 3b 0a 0a 20 20 20 20 20 20 20 20 73 71 6c  ));..        sql
26c0: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20  iteQueryBuilder 
26d0: 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75 65 72  = new SQLiteQuer
26e0: 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20 20 20  yBuilder();.    
26f0: 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42      sqliteQueryB
2700: 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65 73  uilder.setTables
2710: 28 45 4d 50 4c 4f 59 45 45 5f 54 41 42 4c 45 5f  (EMPLOYEE_TABLE_
2720: 4e 41 4d 45 29 3b 0a 20 20 20 20 20 20 20 20 63  NAME);.        c
2730: 75 72 73 6f 72 20 3d 20 73 71 6c 69 74 65 51 75  ursor = sqliteQu
2740: 65 72 79 42 75 69 6c 64 65 72 2e 71 75 65 72 79  eryBuilder.query
2750: 28 6d 44 61 74 61 62 61 73 65 2c 0a 20 20 20 20  (mDatabase,.    
2760: 20 20 20 20 20 20 20 20 20 20 20 20 6e 65 77 20              new 
2770: 53 74 72 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65  String[] { "name
2780: 22 2c 20 22 73 75 6d 28 73 61 6c 61 72 79 29 22  ", "sum(salary)"
2790: 20 7d 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 0a   }, null, null,.
27a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27b0: 22 6e 61 6d 65 22 2c 20 22 73 75 6d 28 73 61 6c  "name", "sum(sal
27c0: 61 72 79 29 3e 31 30 30 30 22 2c 20 22 6e 61 6d  ary)>1000", "nam
27d0: 65 22 2c 20 22 32 22 20 2f 2f 20 6c 69 6d 69 74  e", "2" // limit
27e0: 20 69 73 20 32 0a 20 20 20 20 20 20 20 20 20 20   is 2.          
27f0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20        );.       
2800: 20 61 73 73 65 72 74 4e 6f 74 4e 75 6c 6c 28 63   assertNotNull(c
2810: 75 72 73 6f 72 29 3b 0a 20 20 20 20 20 20 20 20  ursor);.        
2820: 61 73 73 65 72 74 45 71 75 61 6c 73 28 32 2c 20  assertEquals(2, 
2830: 63 75 72 73 6f 72 2e 67 65 74 43 6f 75 6e 74 28  cursor.getCount(
2840: 29 29 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73  ));.        curs
2850: 6f 72 2e 6d 6f 76 65 54 6f 46 69 72 73 74 28 29  or.moveToFirst()
2860: 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ;.        assert
2870: 45 71 75 61 6c 73 28 22 4a 69 6d 22 2c 20 63 75  Equals("Jim", cu
2880: 72 73 6f 72 2e 67 65 74 53 74 72 69 6e 67 28 43  rsor.getString(C
2890: 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e 44 45 58  OLUMN_NAME_INDEX
28a0: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ));.        asse
28b0: 72 74 45 71 75 61 6c 73 28 34 35 30 30 2c 20 63  rtEquals(4500, c
28c0: 75 72 73 6f 72 2e 67 65 74 49 6e 74 28 43 4f 4c  ursor.getInt(COL
28d0: 55 4d 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58  UMN_SALARY_INDEX
28e0: 29 29 3b 0a 20 20 20 20 20 20 20 20 63 75 72 73  ));.        curs
28f0: 6f 72 2e 6d 6f 76 65 54 6f 4e 65 78 74 28 29 3b  or.moveToNext();
2900: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 45  .        assertE
2910: 71 75 61 6c 73 28 22 4d 69 6b 65 22 2c 20 63 75  quals("Mike", cu
2920: 72 73 6f 72 2e 67 65 74 53 74 72 69 6e 67 28 43  rsor.getString(C
2930: 4f 4c 55 4d 4e 5f 4e 41 4d 45 5f 49 4e 44 45 58  OLUMN_NAME_INDEX
2940: 29 29 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ));.        asse
2950: 72 74 45 71 75 61 6c 73 28 34 30 30 30 2c 20 63  rtEquals(4000, c
2960: 75 72 73 6f 72 2e 67 65 74 49 6e 74 28 43 4f 4c  ursor.getInt(COL
2970: 55 4d 4e 5f 53 41 4c 41 52 59 5f 49 4e 44 45 58  UMN_SALARY_INDEX
2980: 29 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70  ));.    }..    p
2990: 75 62 6c 69 63 20 76 6f 69 64 20 74 65 73 74 55  ublic void testU
29a0: 6e 69 6f 6e 51 75 65 72 79 28 29 20 7b 0a 20 20  nionQuery() {.  
29b0: 20 20 20 20 20 20 53 74 72 69 6e 67 20 65 78 70        String exp
29c0: 65 63 74 65 64 3b 0a 20 20 20 20 20 20 20 20 53  ected;.        S
29d0: 74 72 69 6e 67 5b 5d 20 69 6e 6e 65 72 50 72 6f  tring[] innerPro
29e0: 6a 65 63 74 69 6f 6e 20 3d 20 6e 65 77 20 53 74  jection = new St
29f0: 72 69 6e 67 5b 5d 20 7b 22 6e 61 6d 65 22 2c 20  ring[] {"name", 
2a00: 22 61 67 65 22 2c 20 22 6c 6f 63 61 74 69 6f 6e  "age", "location
2a10: 22 7d 3b 0a 20 20 20 20 20 20 20 20 53 51 4c 69  "};.        SQLi
2a20: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 65  teQueryBuilder e
2a30: 6d 70 6c 6f 79 65 65 51 75 65 72 79 42 75 69 6c  mployeeQueryBuil
2a40: 64 65 72 20 3d 20 6e 65 77 20 53 51 4c 69 74 65  der = new SQLite
2a50: 51 75 65 72 79 42 75 69 6c 64 65 72 28 29 3b 0a  QueryBuilder();.
2a60: 20 20 20 20 20 20 20 20 53 51 4c 69 74 65 51 75          SQLiteQu
2a70: 65 72 79 42 75 69 6c 64 65 72 20 70 65 6f 70 6c  eryBuilder peopl
2a80: 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 3d 20  eQueryBuilder = 
2a90: 6e 65 77 20 53 51 4c 69 74 65 51 75 65 72 79 42  new SQLiteQueryB
2aa0: 75 69 6c 64 65 72 28 29 3b 0a 0a 20 20 20 20 20  uilder();..     
2ab0: 20 20 20 65 6d 70 6c 6f 79 65 65 51 75 65 72 79     employeeQuery
2ac0: 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65  Builder.setTable
2ad0: 73 28 22 65 6d 70 6c 6f 79 65 65 22 29 3b 0a 20  s("employee");. 
2ae0: 20 20 20 20 20 20 20 70 65 6f 70 6c 65 51 75 65         peopleQue
2af0: 72 79 42 75 69 6c 64 65 72 2e 73 65 74 54 61 62  ryBuilder.setTab
2b00: 6c 65 73 28 22 70 65 6f 70 6c 65 22 29 3b 0a 0a  les("people");..
2b10: 20 20 20 20 20 20 20 20 53 74 72 69 6e 67 20 65          String e
2b20: 6d 70 6c 6f 79 65 65 53 75 62 51 75 65 72 79 20  mployeeSubQuery 
2b30: 3d 20 65 6d 70 6c 6f 79 65 65 51 75 65 72 79 42  = employeeQueryB
2b40: 75 69 6c 64 65 72 2e 62 75 69 6c 64 55 6e 69 6f  uilder.buildUnio
2b50: 6e 53 75 62 51 75 65 72 79 28 0a 20 20 20 20 20  nSubQuery(.     
2b60: 20 20 20 20 20 20 20 20 20 20 20 22 5f 69 64 22             "_id"
2b70: 2c 20 69 6e 6e 65 72 50 72 6f 6a 65 63 74 69 6f  , innerProjectio
2b80: 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  n,.             
2b90: 20 20 20 6e 75 6c 6c 2c 20 32 2c 20 22 65 6d 70     null, 2, "emp
2ba0: 6c 6f 79 65 65 22 2c 0a 20 20 20 20 20 20 20 20  loyee",.        
2bb0: 20 20 20 20 20 20 20 20 22 61 67 65 3d 32 35 22          "age=25"
2bc0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
2bd0: 20 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75    null, null, nu
2be0: 6c 6c 29 3b 0a 20 20 20 20 20 20 20 20 53 74 72  ll);.        Str
2bf0: 69 6e 67 20 70 65 6f 70 6c 65 53 75 62 51 75 65  ing peopleSubQue
2c00: 72 79 20 3d 20 70 65 6f 70 6c 65 51 75 65 72 79  ry = peopleQuery
2c10: 42 75 69 6c 64 65 72 2e 62 75 69 6c 64 55 6e 69  Builder.buildUni
2c20: 6f 6e 53 75 62 51 75 65 72 79 28 0a 20 20 20 20  onSubQuery(.    
2c30: 20 20 20 20 20 20 20 20 20 20 20 20 22 5f 69 64              "_id
2c40: 22 2c 20 69 6e 6e 65 72 50 72 6f 6a 65 63 74 69  ", innerProjecti
2c50: 6f 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  on,.            
2c60: 20 20 20 20 6e 75 6c 6c 2c 20 32 2c 20 22 70 65      null, 2, "pe
2c70: 6f 70 6c 65 22 2c 0a 20 20 20 20 20 20 20 20 20  ople",.         
2c80: 20 20 20 20 20 20 20 22 6c 6f 63 61 74 69 6f 6e         "location
2c90: 3d 4c 41 22 2c 0a 20 20 20 20 20 20 20 20 20 20  =LA",.          
2ca0: 20 20 20 20 20 20 6e 75 6c 6c 2c 20 6e 75 6c 6c        null, null
2cb0: 2c 20 6e 75 6c 6c 29 3b 0a 20 20 20 20 20 20 20  , null);.       
2cc0: 20 65 78 70 65 63 74 65 64 20 3d 20 22 53 45 4c   expected = "SEL
2cd0: 45 43 54 20 6e 61 6d 65 2c 20 61 67 65 2c 20 6c  ECT name, age, l
2ce0: 6f 63 61 74 69 6f 6e 20 46 52 4f 4d 20 65 6d 70  ocation FROM emp
2cf0: 6c 6f 79 65 65 20 57 48 45 52 45 20 28 61 67 65  loyee WHERE (age
2d00: 3d 32 35 29 22 3b 0a 20 20 20 20 20 20 20 20 61  =25)";.        a
2d10: 73 73 65 72 74 45 71 75 61 6c 73 28 65 78 70 65  ssertEquals(expe
2d20: 63 74 65 64 2c 20 65 6d 70 6c 6f 79 65 65 53 75  cted, employeeSu
2d30: 62 51 75 65 72 79 29 3b 0a 20 20 20 20 20 20 20  bQuery);.       
2d40: 20 65 78 70 65 63 74 65 64 20 3d 20 22 53 45 4c   expected = "SEL
2d50: 45 43 54 20 6e 61 6d 65 2c 20 61 67 65 2c 20 6c  ECT name, age, l
2d60: 6f 63 61 74 69 6f 6e 20 46 52 4f 4d 20 70 65 6f  ocation FROM peo
2d70: 70 6c 65 20 57 48 45 52 45 20 28 6c 6f 63 61 74  ple WHERE (locat
2d80: 69 6f 6e 3d 4c 41 29 22 3b 0a 20 20 20 20 20 20  ion=LA)";.      
2d90: 20 20 61 73 73 65 72 74 45 71 75 61 6c 73 28 65    assertEquals(e
2da0: 78 70 65 63 74 65 64 2c 20 70 65 6f 70 6c 65 53  xpected, peopleS
2db0: 75 62 51 75 65 72 79 29 3b 0a 0a 20 20 20 20 20  ubQuery);..     
2dc0: 20 20 20 53 51 4c 69 74 65 51 75 65 72 79 42 75     SQLiteQueryBu
2dd0: 69 6c 64 65 72 20 75 6e 69 6f 6e 51 75 65 72 79  ilder unionQuery
2de0: 42 75 69 6c 64 65 72 20 3d 20 6e 65 77 20 53 51  Builder = new SQ
2df0: 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  LiteQueryBuilder
2e00: 28 29 3b 0a 0a 20 20 20 20 20 20 20 20 75 6e 69  ();..        uni
2e10: 6f 6e 51 75 65 72 79 42 75 69 6c 64 65 72 2e 73  onQueryBuilder.s
2e20: 65 74 44 69 73 74 69 6e 63 74 28 74 72 75 65 29  etDistinct(true)
2e30: 3b 0a 0a 20 20 20 20 20 20 20 20 53 74 72 69 6e  ;..        Strin
2e40: 67 20 75 6e 69 6f 6e 51 75 65 72 79 20 3d 20 75  g unionQuery = u
2e50: 6e 69 6f 6e 51 75 65 72 79 42 75 69 6c 64 65 72  nionQueryBuilder
2e60: 2e 62 75 69 6c 64 55 6e 69 6f 6e 51 75 65 72 79  .buildUnionQuery
2e70: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
2e80: 20 20 6e 65 77 20 53 74 72 69 6e 67 5b 5d 20 7b    new String[] {
2e90: 20 65 6d 70 6c 6f 79 65 65 53 75 62 51 75 65 72   employeeSubQuer
2ea0: 79 2c 20 70 65 6f 70 6c 65 53 75 62 51 75 65 72  y, peopleSubQuer
2eb0: 79 20 7d 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 29  y }, null, null)
2ec0: 3b 0a 20 20 20 20 20 20 20 20 65 78 70 65 63 74  ;.        expect
2ed0: 65 64 20 3d 20 22 53 45 4c 45 43 54 20 6e 61 6d  ed = "SELECT nam
2ee0: 65 2c 20 61 67 65 2c 20 6c 6f 63 61 74 69 6f 6e  e, age, location
2ef0: 20 46 52 4f 4d 20 65 6d 70 6c 6f 79 65 65 20 57   FROM employee W
2f00: 48 45 52 45 20 28 61 67 65 3d 32 35 29 20 22 20  HERE (age=25) " 
2f10: 2b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  +.              
2f20: 20 20 22 55 4e 49 4f 4e 20 53 45 4c 45 43 54 20    "UNION SELECT 
2f30: 6e 61 6d 65 2c 20 61 67 65 2c 20 6c 6f 63 61 74  name, age, locat
2f40: 69 6f 6e 20 46 52 4f 4d 20 70 65 6f 70 6c 65 20  ion FROM people 
2f50: 57 48 45 52 45 20 28 6c 6f 63 61 74 69 6f 6e 3d  WHERE (location=
2f60: 4c 41 29 22 3b 0a 20 20 20 20 20 20 20 20 61 73  LA)";.        as
2f70: 73 65 72 74 45 71 75 61 6c 73 28 65 78 70 65 63  sertEquals(expec
2f80: 74 65 64 2c 20 75 6e 69 6f 6e 51 75 65 72 79 29  ted, unionQuery)
2f90: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 75 62  ;.    }..    pub
2fa0: 6c 69 63 20 76 6f 69 64 20 74 65 73 74 43 61 6e  lic void testCan
2fb0: 63 65 6c 61 62 6c 65 51 75 65 72 79 5f 57 68 65  celableQuery_Whe
2fc0: 6e 4e 6f 74 43 61 6e 63 65 6c 65 64 5f 52 65 74  nNotCanceled_Ret
2fd0: 75 72 6e 73 52 65 73 75 6c 74 53 65 74 28 29 20  urnsResultSet() 
2fe0: 7b 0a 20 20 20 20 20 20 20 20 63 72 65 61 74 65  {.        create
2ff0: 45 6d 70 6c 6f 79 65 65 54 61 62 6c 65 28 29 3b  EmployeeTable();
3000: 0a 0a 20 20 20 20 20 20 20 20 43 61 6e 63 65 6c  ..        Cancel
3010: 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20 63 61 6e  lationSignal can
3020: 63 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20  cellationSignal 
3030: 3d 20 6e 65 77 20 43 61 6e 63 65 6c 6c 61 74 69  = new Cancellati
3040: 6f 6e 53 69 67 6e 61 6c 28 29 3b 0a 20 20 20 20  onSignal();.    
3050: 20 20 20 20 53 51 4c 69 74 65 51 75 65 72 79 42      SQLiteQueryB
3060: 75 69 6c 64 65 72 20 73 71 6c 69 74 65 51 75 65  uilder sqliteQue
3070: 72 79 42 75 69 6c 64 65 72 20 3d 20 6e 65 77 20  ryBuilder = new 
3080: 53 51 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64  SQLiteQueryBuild
3090: 65 72 28 29 3b 0a 20 20 20 20 20 20 20 20 73 71  er();.        sq
30a0: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
30b0: 2e 73 65 74 54 61 62 6c 65 73 28 22 45 6d 70 6c  .setTables("Empl
30c0: 6f 79 65 65 22 29 3b 0a 20 20 20 20 20 20 20 20  oyee");.        
30d0: 43 75 72 73 6f 72 20 63 75 72 73 6f 72 20 3d 20  Cursor cursor = 
30e0: 73 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64  sqliteQueryBuild
30f0: 65 72 2e 71 75 65 72 79 28 6d 44 61 74 61 62 61  er.query(mDataba
3100: 73 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  se,.            
3110: 20 20 20 20 6e 65 77 20 53 74 72 69 6e 67 5b 5d      new String[]
3120: 20 7b 20 22 6e 61 6d 65 22 2c 20 22 73 75 6d 28   { "name", "sum(
3130: 73 61 6c 61 72 79 29 22 20 7d 2c 20 6e 75 6c 6c  salary)" }, null
3140: 2c 20 6e 75 6c 6c 2c 0a 20 20 20 20 20 20 20 20  , null,.        
3150: 20 20 20 20 20 20 20 20 22 6e 61 6d 65 22 2c 20          "name", 
3160: 22 73 75 6d 28 73 61 6c 61 72 79 29 3e 31 30 30  "sum(salary)>100
3170: 30 22 2c 20 22 6e 61 6d 65 22 2c 20 6e 75 6c 6c  0", "name", null
3180: 2c 20 63 61 6e 63 65 6c 6c 61 74 69 6f 6e 53 69  , cancellationSi
3190: 67 6e 61 6c 29 3b 0a 0a 20 20 20 20 20 20 20 20  gnal);..        
31a0: 61 73 73 65 72 74 45 71 75 61 6c 73 28 33 2c 20  assertEquals(3, 
31b0: 63 75 72 73 6f 72 2e 67 65 74 43 6f 75 6e 74 28  cursor.getCount(
31c0: 29 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70  ));.    }..    p
31d0: 75 62 6c 69 63 20 76 6f 69 64 20 74 65 73 74 43  ublic void testC
31e0: 61 6e 63 65 6c 61 62 6c 65 51 75 65 72 79 5f 57  ancelableQuery_W
31f0: 68 65 6e 43 61 6e 63 65 6c 65 64 42 65 66 6f 72  henCanceledBefor
3200: 65 51 75 65 72 79 5f 54 68 72 6f 77 73 49 6d 6d  eQuery_ThrowsImm
3210: 65 64 69 61 74 65 6c 79 28 29 20 7b 0a 20 20 20  ediately() {.   
3220: 20 20 20 20 20 63 72 65 61 74 65 45 6d 70 6c 6f       createEmplo
3230: 79 65 65 54 61 62 6c 65 28 29 3b 0a 0a 20 20 20  yeeTable();..   
3240: 20 20 20 20 20 43 61 6e 63 65 6c 6c 61 74 69 6f       Cancellatio
3250: 6e 53 69 67 6e 61 6c 20 63 61 6e 63 65 6c 6c 61  nSignal cancella
3260: 74 69 6f 6e 53 69 67 6e 61 6c 20 3d 20 6e 65 77  tionSignal = new
3270: 20 43 61 6e 63 65 6c 6c 61 74 69 6f 6e 53 69 67   CancellationSig
3280: 6e 61 6c 28 29 3b 0a 20 20 20 20 20 20 20 20 53  nal();.        S
3290: 51 4c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  QLiteQueryBuilde
32a0: 72 20 73 71 6c 69 74 65 51 75 65 72 79 42 75 69  r sqliteQueryBui
32b0: 6c 64 65 72 20 3d 20 6e 65 77 20 53 51 4c 69 74  lder = new SQLit
32c0: 65 51 75 65 72 79 42 75 69 6c 64 65 72 28 29 3b  eQueryBuilder();
32d0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 51  .        sqliteQ
32e0: 75 65 72 79 42 75 69 6c 64 65 72 2e 73 65 74 54  ueryBuilder.setT
32f0: 61 62 6c 65 73 28 22 45 6d 70 6c 6f 79 65 65 22  ables("Employee"
3300: 29 3b 0a 0a 20 20 20 20 20 20 20 20 63 61 6e 63  );..        canc
3310: 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 2e 63  ellationSignal.c
3320: 61 6e 63 65 6c 28 29 3b 0a 20 20 20 20 20 20 20  ancel();.       
3330: 20 74 72 79 20 7b 0a 20 20 20 20 20 20 20 20 20   try {.         
3340: 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42 75     sqliteQueryBu
3350: 69 6c 64 65 72 2e 71 75 65 72 79 28 6d 44 61 74  ilder.query(mDat
3360: 61 62 61 73 65 2c 0a 20 20 20 20 20 20 20 20 20  abase,.         
3370: 20 20 20 20 20 20 20 20 20 20 20 6e 65 77 20 53             new S
3380: 74 72 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22  tring[] { "name"
3390: 2c 20 22 73 75 6d 28 73 61 6c 61 72 79 29 22 20  , "sum(salary)" 
33a0: 7d 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 0a 20  }, null, null,. 
33b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33c0: 20 20 20 22 6e 61 6d 65 22 2c 20 22 73 75 6d 28     "name", "sum(
33d0: 73 61 6c 61 72 79 29 3e 31 30 30 30 22 2c 20 22  salary)>1000", "
33e0: 6e 61 6d 65 22 2c 20 6e 75 6c 6c 2c 20 63 61 6e  name", null, can
33f0: 63 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 29  cellationSignal)
3400: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 61  ;.            fa
3410: 69 6c 28 22 45 78 70 65 63 74 65 64 20 4f 70 65  il("Expected Ope
3420: 72 61 74 69 6f 6e 43 61 6e 63 65 6c 65 64 45 78  rationCanceledEx
3430: 63 65 70 74 69 6f 6e 22 29 3b 0a 20 20 20 20 20  ception");.     
3440: 20 20 20 7d 20 63 61 74 63 68 20 28 4f 70 65 72     } catch (Oper
3450: 61 74 69 6f 6e 43 61 6e 63 65 6c 65 64 45 78 63  ationCanceledExc
3460: 65 70 74 69 6f 6e 20 65 78 29 20 7b 0a 20 20 20  eption ex) {.   
3470: 20 20 20 20 20 20 20 20 20 2f 2f 20 65 78 70 65           // expe
3480: 63 74 65 64 0a 20 20 20 20 20 20 20 20 7d 0a 20  cted.        }. 
3490: 20 20 20 7d 0a 0a 20 20 20 20 70 75 62 6c 69 63     }..    public
34a0: 20 76 6f 69 64 20 74 65 73 74 43 61 6e 63 65 6c   void testCancel
34b0: 61 62 6c 65 51 75 65 72 79 5f 57 68 65 6e 43 61  ableQuery_WhenCa
34c0: 6e 63 65 6c 65 64 41 66 74 65 72 51 75 65 72 79  nceledAfterQuery
34d0: 5f 54 68 72 6f 77 73 57 68 65 6e 45 78 65 63 75  _ThrowsWhenExecu
34e0: 74 65 64 28 29 20 7b 0a 20 20 20 20 20 20 20 20  ted() {.        
34f0: 63 72 65 61 74 65 45 6d 70 6c 6f 79 65 65 54 61  createEmployeeTa
3500: 62 6c 65 28 29 3b 0a 0a 20 20 20 20 20 20 20 20  ble();..        
3510: 43 61 6e 63 65 6c 6c 61 74 69 6f 6e 53 69 67 6e  CancellationSign
3520: 61 6c 20 63 61 6e 63 65 6c 6c 61 74 69 6f 6e 53  al cancellationS
3530: 69 67 6e 61 6c 20 3d 20 6e 65 77 20 43 61 6e 63  ignal = new Canc
3540: 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 28 29  ellationSignal()
3550: 3b 0a 20 20 20 20 20 20 20 20 53 51 4c 69 74 65  ;.        SQLite
3560: 51 75 65 72 79 42 75 69 6c 64 65 72 20 73 71 6c  QueryBuilder sql
3570: 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20  iteQueryBuilder 
3580: 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75 65 72  = new SQLiteQuer
3590: 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20 20 20  yBuilder();.    
35a0: 20 20 20 20 73 71 6c 69 74 65 51 75 65 72 79 42      sqliteQueryB
35b0: 75 69 6c 64 65 72 2e 73 65 74 54 61 62 6c 65 73  uilder.setTables
35c0: 28 22 45 6d 70 6c 6f 79 65 65 22 29 3b 0a 0a 20  ("Employee");.. 
35d0: 20 20 20 20 20 20 20 43 75 72 73 6f 72 20 63 75         Cursor cu
35e0: 72 73 6f 72 20 3d 20 73 71 6c 69 74 65 51 75 65  rsor = sqliteQue
35f0: 72 79 42 75 69 6c 64 65 72 2e 71 75 65 72 79 28  ryBuilder.query(
3600: 6d 44 61 74 61 62 61 73 65 2c 0a 20 20 20 20 20  mDatabase,.     
3610: 20 20 20 20 20 20 20 20 20 20 20 6e 65 77 20 53             new S
3620: 74 72 69 6e 67 5b 5d 20 7b 20 22 6e 61 6d 65 22  tring[] { "name"
3630: 2c 20 22 73 75 6d 28 73 61 6c 61 72 79 29 22 20  , "sum(salary)" 
3640: 7d 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 0a 20  }, null, null,. 
3650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
3660: 6e 61 6d 65 22 2c 20 22 73 75 6d 28 73 61 6c 61  name", "sum(sala
3670: 72 79 29 3e 31 30 30 30 22 2c 20 22 6e 61 6d 65  ry)>1000", "name
3680: 22 2c 20 6e 75 6c 6c 2c 20 63 61 6e 63 65 6c 6c  ", null, cancell
3690: 61 74 69 6f 6e 53 69 67 6e 61 6c 29 3b 0a 0a 20  ationSignal);.. 
36a0: 20 20 20 20 20 20 20 63 61 6e 63 65 6c 6c 61 74         cancellat
36b0: 69 6f 6e 53 69 67 6e 61 6c 2e 63 61 6e 63 65 6c  ionSignal.cancel
36c0: 28 29 3b 0a 20 20 20 20 20 20 20 20 74 72 79 20  ();.        try 
36d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 75  {.            cu
36e0: 72 73 6f 72 2e 67 65 74 43 6f 75 6e 74 28 29 3b  rsor.getCount();
36f0: 20 2f 2f 20 66 6f 72 63 65 20 65 78 65 63 75 74   // force execut
3700: 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20  ion.            
3710: 66 61 69 6c 28 22 45 78 70 65 63 74 65 64 20 4f  fail("Expected O
3720: 70 65 72 61 74 69 6f 6e 43 61 6e 63 65 6c 65 64  perationCanceled
3730: 45 78 63 65 70 74 69 6f 6e 22 29 3b 0a 20 20 20  Exception");.   
3740: 20 20 20 20 20 7d 20 63 61 74 63 68 20 28 4f 70       } catch (Op
3750: 65 72 61 74 69 6f 6e 43 61 6e 63 65 6c 65 64 45  erationCanceledE
3760: 78 63 65 70 74 69 6f 6e 20 65 78 29 20 7b 0a 20  xception ex) {. 
3770: 20 20 20 20 20 20 20 20 20 20 20 2f 2f 20 65 78             // ex
3780: 70 65 63 74 65 64 0a 20 20 20 20 20 20 20 20 7d  pected.        }
3790: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 75 62 6c  .    }..    publ
37a0: 69 63 20 76 6f 69 64 20 74 65 73 74 43 61 6e 63  ic void testCanc
37b0: 65 6c 61 62 6c 65 51 75 65 72 79 5f 57 68 65 6e  elableQuery_When
37c0: 43 61 6e 63 65 6c 65 64 44 75 65 54 6f 43 6f 6e  CanceledDueToCon
37d0: 74 65 6e 74 69 6f 6e 5f 53 74 6f 70 73 57 61 69  tention_StopsWai
37e0: 74 69 6e 67 41 6e 64 54 68 72 6f 77 73 28 29 20  tingAndThrows() 
37f0: 7b 0a 20 20 20 20 20 20 20 20 63 72 65 61 74 65  {.        create
3800: 45 6d 70 6c 6f 79 65 65 54 61 62 6c 65 28 29 3b  EmployeeTable();
3810: 0a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 28 69  ..        for (i
3820: 6e 74 20 69 20 3d 20 30 3b 20 69 20 3c 20 35 3b  nt i = 0; i < 5;
3830: 20 69 2b 2b 29 20 7b 0a 20 20 20 20 20 20 20 20   i++) {.        
3840: 20 20 20 20 66 69 6e 61 6c 20 43 61 6e 63 65 6c      final Cancel
3850: 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20 63 61 6e  lationSignal can
3860: 63 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20  cellationSignal 
3870: 3d 20 6e 65 77 20 43 61 6e 63 65 6c 6c 61 74 69  = new Cancellati
3880: 6f 6e 53 69 67 6e 61 6c 28 29 3b 0a 20 20 20 20  onSignal();.    
3890: 20 20 20 20 20 20 20 20 66 69 6e 61 6c 20 53 65          final Se
38a0: 6d 61 70 68 6f 72 65 20 62 61 72 72 69 65 72 31  maphore barrier1
38b0: 20 3d 20 6e 65 77 20 53 65 6d 61 70 68 6f 72 65   = new Semaphore
38c0: 28 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  (0);.           
38d0: 20 66 69 6e 61 6c 20 53 65 6d 61 70 68 6f 72 65   final Semaphore
38e0: 20 62 61 72 72 69 65 72 32 20 3d 20 6e 65 77 20   barrier2 = new 
38f0: 53 65 6d 61 70 68 6f 72 65 28 30 29 3b 0a 20 20  Semaphore(0);.  
3900: 20 20 20 20 20 20 20 20 20 20 54 68 72 65 61 64            Thread
3910: 20 63 6f 6e 74 65 6e 74 69 6f 6e 54 68 72 65 61   contentionThrea
3920: 64 20 3d 20 6e 65 77 20 54 68 72 65 61 64 28 29  d = new Thread()
3930: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
3940: 20 20 20 40 4f 76 65 72 72 69 64 65 0a 20 20 20     @Override.   
3950: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 75 62               pub
3960: 6c 69 63 20 76 6f 69 64 20 72 75 6e 28 29 20 7b  lic void run() {
3970: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3980: 20 20 20 20 20 6d 44 61 74 61 62 61 73 65 2e 62       mDatabase.b
3990: 65 67 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 28  eginTransaction(
39a0: 29 3b 20 2f 2f 20 61 63 71 75 69 72 65 20 74 68  ); // acquire th
39b0: 65 20 6f 6e 6c 79 20 61 76 61 69 6c 61 62 6c 65  e only available
39c0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a 20 20 20 20   connection.    
39d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39e0: 62 61 72 72 69 65 72 31 2e 72 65 6c 65 61 73 65  barrier1.release
39f0: 28 29 3b 20 2f 2f 20 72 65 6c 65 61 73 65 20 71  (); // release q
3a00: 75 65 72 79 20 74 6f 20 73 74 61 72 74 20 72 75  uery to start ru
3a10: 6e 6e 69 6e 67 0a 20 20 20 20 20 20 20 20 20 20  nning.          
3a20: 20 20 20 20 20 20 20 20 20 20 74 72 79 20 7b 0a            try {.
3a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a40: 20 20 20 20 20 20 20 20 62 61 72 72 69 65 72 32          barrier2
3a50: 2e 61 63 71 75 69 72 65 28 29 3b 20 2f 2f 20 77  .acquire(); // w
3a60: 61 69 74 20 66 6f 72 20 74 65 73 74 20 74 6f 20  ait for test to 
3a70: 65 6e 64 0a 20 20 20 20 20 20 20 20 20 20 20 20  end.            
3a80: 20 20 20 20 20 20 20 20 7d 20 63 61 74 63 68 20          } catch 
3a90: 28 49 6e 74 65 72 72 75 70 74 65 64 45 78 63 65  (InterruptedExce
3aa0: 70 74 69 6f 6e 20 65 29 20 7b 0a 20 20 20 20 20  ption e) {.     
3ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d                 }
3ac0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3ad0: 20 20 20 20 20 6d 44 61 74 61 62 61 73 65 2e 65       mDatabase.e
3ae0: 6e 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 3b  ndTransaction();
3af0: 20 2f 2f 20 72 65 6c 65 61 73 65 20 74 68 65 20   // release the 
3b00: 63 6f 6e 6e 65 63 74 69 6f 6e 0a 20 20 20 20 20  connection.     
3b10: 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
3b20: 20 20 20 20 20 20 20 20 20 7d 3b 0a 20 20 20 20           };.    
3b30: 20 20 20 20 20 20 20 20 54 68 72 65 61 64 20 63          Thread c
3b40: 61 6e 63 65 6c 6c 61 74 69 6f 6e 54 68 72 65 61  ancellationThrea
3b50: 64 20 3d 20 6e 65 77 20 54 68 72 65 61 64 28 29  d = new Thread()
3b60: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
3b70: 20 20 20 40 4f 76 65 72 72 69 64 65 0a 20 20 20     @Override.   
3b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 75 62               pub
3b90: 6c 69 63 20 76 6f 69 64 20 72 75 6e 28 29 20 7b  lic void run() {
3ba0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3bb0: 20 20 20 20 20 74 72 79 20 7b 0a 20 20 20 20 20       try {.     
3bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3bd0: 20 20 20 54 68 72 65 61 64 2e 73 6c 65 65 70 28     Thread.sleep(
3be0: 33 30 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  300);.          
3bf0: 20 20 20 20 20 20 20 20 20 20 7d 20 63 61 74 63            } catc
3c00: 68 20 28 49 6e 74 65 72 72 75 70 74 65 64 45 78  h (InterruptedEx
3c10: 63 65 70 74 69 6f 6e 20 65 78 29 20 7b 0a 20 20  ception ex) {.  
3c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3c30: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
3c40: 20 20 20 20 20 20 20 20 63 61 6e 63 65 6c 6c 61          cancella
3c50: 74 69 6f 6e 53 69 67 6e 61 6c 2e 63 61 6e 63 65  tionSignal.cance
3c60: 6c 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  l();.           
3c70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
3c80: 20 20 20 7d 3b 0a 20 20 20 20 20 20 20 20 20 20     };.          
3c90: 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20 20 20    try {.        
3ca0: 20 20 20 20 20 20 20 20 53 51 4c 69 74 65 51 75          SQLiteQu
3cb0: 65 72 79 42 75 69 6c 64 65 72 20 73 71 6c 69 74  eryBuilder sqlit
3cc0: 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 3d 20  eQueryBuilder = 
3cd0: 6e 65 77 20 53 51 4c 69 74 65 51 75 65 72 79 42  new SQLiteQueryB
3ce0: 75 69 6c 64 65 72 28 29 3b 0a 20 20 20 20 20 20  uilder();.      
3cf0: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
3d00: 51 75 65 72 79 42 75 69 6c 64 65 72 2e 73 65 74  QueryBuilder.set
3d10: 54 61 62 6c 65 73 28 22 45 6d 70 6c 6f 79 65 65  Tables("Employee
3d20: 22 29 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 20  ");..           
3d30: 20 20 20 20 20 63 6f 6e 74 65 6e 74 69 6f 6e 54       contentionT
3d40: 68 72 65 61 64 2e 73 74 61 72 74 28 29 3b 0a 20  hread.start();. 
3d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63                 c
3d60: 61 6e 63 65 6c 6c 61 74 69 6f 6e 54 68 72 65 61  ancellationThrea
3d70: 64 2e 73 74 61 72 74 28 29 3b 0a 0a 20 20 20 20  d.start();..    
3d80: 20 20 20 20 20 20 20 20 20 20 20 20 74 72 79 20              try 
3d90: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
3da0: 20 20 20 20 20 20 62 61 72 72 69 65 72 31 2e 61        barrier1.a
3db0: 63 71 75 69 72 65 28 29 3b 20 2f 2f 20 77 61 69  cquire(); // wai
3dc0: 74 20 66 6f 72 20 63 6f 6e 74 65 6e 74 69 6f 6e  t for contention
3dd0: 20 74 68 72 65 61 64 20 74 6f 20 73 74 61 72 74   thread to start
3de0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20 20 20   transaction.   
3df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 20 63               } c
3e00: 61 74 63 68 20 28 49 6e 74 65 72 72 75 70 74 65  atch (Interrupte
3e10: 64 45 78 63 65 70 74 69 6f 6e 20 65 29 20 7b 0a  dException e) {.
3e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e30: 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  }..             
3e40: 20 20 20 66 69 6e 61 6c 20 6c 6f 6e 67 20 73 74     final long st
3e50: 61 72 74 54 69 6d 65 20 3d 20 53 79 73 74 65 6d  artTime = System
3e60: 2e 6e 61 6e 6f 54 69 6d 65 28 29 3b 0a 20 20 20  .nanoTime();.   
3e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 74 72 79               try
3e80: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
3e90: 20 20 20 20 20 20 20 43 75 72 73 6f 72 20 63 75         Cursor cu
3ea0: 72 73 6f 72 20 3d 20 73 71 6c 69 74 65 51 75 65  rsor = sqliteQue
3eb0: 72 79 42 75 69 6c 64 65 72 2e 71 75 65 72 79 28  ryBuilder.query(
3ec0: 6d 44 61 74 61 62 61 73 65 2c 0a 20 20 20 20 20  mDatabase,.     
3ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ee0: 20 20 20 20 20 20 20 6e 65 77 20 53 74 72 69 6e         new Strin
3ef0: 67 5b 5d 20 7b 20 22 6e 61 6d 65 22 2c 20 22 73  g[] { "name", "s
3f00: 75 6d 28 73 61 6c 61 72 79 29 22 20 7d 2c 20 6e  um(salary)" }, n
3f10: 75 6c 6c 2c 20 6e 75 6c 6c 2c 0a 20 20 20 20 20  ull, null,.     
3f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f30: 20 20 20 20 20 20 20 22 6e 61 6d 65 22 2c 20 22         "name", "
3f40: 73 75 6d 28 73 61 6c 61 72 79 29 3e 31 30 30 30  sum(salary)>1000
3f50: 22 2c 20 22 6e 61 6d 65 22 2c 20 6e 75 6c 6c 2c  ", "name", null,
3f60: 20 63 61 6e 63 65 6c 6c 61 74 69 6f 6e 53 69 67   cancellationSig
3f70: 6e 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  nal);.          
3f80: 20 20 20 20 20 20 20 20 20 20 63 75 72 73 6f 72            cursor
3f90: 2e 67 65 74 43 6f 75 6e 74 28 29 3b 20 2f 2f 20  .getCount(); // 
3fa0: 66 6f 72 63 65 20 65 78 65 63 75 74 69 6f 6e 0a  force execution.
3fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3fc0: 20 20 20 20 66 61 69 6c 28 22 45 78 70 65 63 74      fail("Expect
3fd0: 65 64 20 4f 70 65 72 61 74 69 6f 6e 43 61 6e 63  ed OperationCanc
3fe0: 65 6c 65 64 45 78 63 65 70 74 69 6f 6e 22 29 3b  eledException");
3ff0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4000: 20 7d 20 63 61 74 63 68 20 28 4f 70 65 72 61 74   } catch (Operat
4010: 69 6f 6e 43 61 6e 63 65 6c 65 64 45 78 63 65 70  ionCanceledExcep
4020: 74 69 6f 6e 20 65 78 29 20 7b 0a 20 20 20 20 20  tion ex) {.     
4030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4040: 2f 20 65 78 70 65 63 74 65 64 0a 20 20 20 20 20  / expected.     
4050: 20 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20             }..  
4060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2f                //
4070: 20 57 65 20 77 61 6e 74 20 74 6f 20 63 6f 6e 66   We want to conf
4080: 69 72 6d 20 74 68 61 74 20 74 68 65 20 71 75 65  irm that the que
4090: 72 79 20 72 65 61 6c 6c 79 20 77 61 73 20 62 6c  ry really was bl
40a0: 6f 63 6b 65 64 20 74 72 79 69 6e 67 20 74 6f 20  ocked trying to 
40b0: 61 63 71 75 69 72 65 20 61 0a 20 20 20 20 20 20  acquire a.      
40c0: 20 20 20 20 20 20 20 20 20 20 2f 2f 20 63 6f 6e            // con
40d0: 6e 65 63 74 69 6f 6e 20 66 6f 72 20 61 20 63 65  nection for a ce
40e0: 72 74 61 69 6e 20 61 6d 6f 75 6e 74 20 6f 66 20  rtain amount of 
40f0: 74 69 6d 65 20 62 65 66 6f 72 65 20 69 74 20 77  time before it w
4100: 61 73 20 66 72 65 65 64 20 62 79 20 63 61 6e 63  as freed by canc
4110: 65 6c 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20  el..            
4120: 20 20 20 20 66 69 6e 61 6c 20 6c 6f 6e 67 20 77      final long w
4130: 61 69 74 54 69 6d 65 20 3d 20 53 79 73 74 65 6d  aitTime = System
4140: 2e 6e 61 6e 6f 54 69 6d 65 28 29 20 2d 20 73 74  .nanoTime() - st
4150: 61 72 74 54 69 6d 65 3b 0a 20 20 20 20 20 20 20  artTime;.       
4160: 20 20 20 20 20 20 20 20 20 69 66 20 28 77 61 69           if (wai
4170: 74 54 69 6d 65 20 3e 20 31 35 30 20 2a 20 31 30  tTime > 150 * 10
4180: 30 30 30 30 30 4c 29 20 7b 0a 20 20 20 20 20 20  00000L) {.      
4190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
41a0: 74 75 72 6e 3b 20 2f 2f 20 73 75 63 63 65 73 73  turn; // success
41b0: 21 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  !.              
41c0: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
41d0: 7d 20 66 69 6e 61 6c 6c 79 20 7b 0a 20 20 20 20  } finally {.    
41e0: 20 20 20 20 20 20 20 20 20 20 20 20 62 61 72 72              barr
41f0: 69 65 72 31 2e 72 65 6c 65 61 73 65 28 29 3b 0a  ier1.release();.
4200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4210: 62 61 72 72 69 65 72 32 2e 72 65 6c 65 61 73 65  barrier2.release
4220: 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ();.            
4230: 20 20 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20      try {.      
4240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f                co
4250: 6e 74 65 6e 74 69 6f 6e 54 68 72 65 61 64 2e 6a  ntentionThread.j
4260: 6f 69 6e 28 29 3b 0a 20 20 20 20 20 20 20 20 20  oin();.         
4270: 20 20 20 20 20 20 20 20 20 20 20 63 61 6e 63 65             cance
4280: 6c 6c 61 74 69 6f 6e 54 68 72 65 61 64 2e 6a 6f  llationThread.jo
4290: 69 6e 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20  in();.          
42a0: 20 20 20 20 20 20 7d 20 63 61 74 63 68 20 28 49        } catch (I
42b0: 6e 74 65 72 72 75 70 74 65 64 45 78 63 65 70 74  nterruptedExcept
42c0: 69 6f 6e 20 65 29 20 7b 0a 20 20 20 20 20 20 20  ion e) {.       
42d0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
42e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
42f0: 20 7d 0a 0a 20 20 20 20 20 20 20 20 2f 2f 20 4f   }..        // O
4300: 63 63 61 73 69 6f 6e 61 6c 6c 79 20 77 65 20 6d  ccasionally we m
4310: 69 67 68 74 20 6d 69 73 73 20 74 68 65 20 74 69  ight miss the ti
4320: 6d 69 6e 67 20 64 65 61 64 6c 69 6e 65 20 64 75  ming deadline du
4330: 65 20 74 6f 20 66 61 63 74 6f 72 73 20 69 6e 20  e to factors in 
4340: 74 68 65 0a 20 20 20 20 20 20 20 20 2f 2f 20 65  the.        // e
4350: 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20 62 75 74 20  nvironment, but 
4360: 69 66 20 61 66 74 65 72 20 73 65 76 65 72 61 6c  if after several
4370: 20 74 72 69 61 6c 73 20 77 65 20 73 74 69 6c 6c   trials we still
4380: 20 63 6f 75 6c 64 6e 27 74 20 64 65 6d 6f 6e 73   couldn't demons
4390: 74 72 61 74 65 0a 20 20 20 20 20 20 20 20 2f 2f  trate.        //
43a0: 20 74 68 61 74 20 74 68 65 20 71 75 65 72 79 20   that the query 
43b0: 77 61 73 20 62 6c 6f 63 6b 65 64 2c 20 74 68 65  was blocked, the
43c0: 6e 20 74 68 65 20 74 65 73 74 20 6d 75 73 74 20  n the test must 
43d0: 62 65 20 62 72 6f 6b 65 6e 2e 0a 20 20 20 20 20  be broken..     
43e0: 20 20 20 66 61 69 6c 28 22 43 6f 75 6c 64 20 6e     fail("Could n
43f0: 6f 74 20 70 72 6f 76 65 20 74 68 61 74 20 74 68  ot prove that th
4400: 65 20 71 75 65 72 79 20 61 63 74 75 61 6c 6c 79  e query actually
4410: 20 62 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 20   blocked before 
4420: 63 61 6e 63 65 6c 28 29 20 77 61 73 20 63 61 6c  cancel() was cal
4430: 6c 65 64 2e 22 29 3b 0a 20 20 20 20 7d 0a 0a 20  led.");.    }.. 
4440: 20 20 20 70 75 62 6c 69 63 20 76 6f 69 64 20 74     public void t
4450: 65 73 74 43 61 6e 63 65 6c 61 62 6c 65 51 75 65  estCancelableQue
4460: 72 79 5f 57 68 65 6e 43 61 6e 63 65 6c 65 64 44  ry_WhenCanceledD
4470: 75 72 69 6e 67 4c 6f 6e 67 52 75 6e 6e 69 6e 67  uringLongRunning
4480: 51 75 65 72 79 5f 43 61 6e 63 65 6c 73 51 75 65  Query_CancelsQue
4490: 72 79 41 6e 64 54 68 72 6f 77 73 28 29 20 7b 0a  ryAndThrows() {.
44a0: 20 20 20 20 20 20 20 20 2f 2f 20 50 6f 70 75 6c          // Popul
44b0: 61 74 65 20 61 20 74 61 62 6c 65 20 77 69 74 68  ate a table with
44c0: 20 61 20 62 75 6e 63 68 20 6f 66 20 69 6e 74 65   a bunch of inte
44d0: 67 65 72 73 2e 0a 20 20 20 20 20 20 20 20 6d 44  gers..        mD
44e0: 61 74 61 62 61 73 65 2e 65 78 65 63 53 51 4c 28  atabase.execSQL(
44f0: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 20  "CREATE TABLE x 
4500: 28 76 20 49 4e 54 45 47 45 52 29 3b 22 29 3b 0a  (v INTEGER);");.
4510: 20 20 20 20 20 20 20 20 66 6f 72 20 28 69 6e 74          for (int
4520: 20 69 20 3d 20 30 3b 20 69 20 3c 20 31 30 30 3b   i = 0; i < 100;
4530: 20 69 2b 2b 29 20 7b 0a 20 20 20 20 20 20 20 20   i++) {.        
4540: 20 20 20 20 6d 44 61 74 61 62 61 73 65 2e 65 78      mDatabase.ex
4550: 65 63 53 51 4c 28 22 49 4e 53 45 52 54 20 49 4e  ecSQL("INSERT IN
4560: 54 4f 20 78 20 56 41 4c 55 45 53 20 28 3f 29 22  TO x VALUES (?)"
4570: 2c 20 6e 65 77 20 4f 62 6a 65 63 74 5b 5d 20 7b  , new Object[] {
4580: 20 69 20 7d 29 3b 0a 20 20 20 20 20 20 20 20 7d   i });.        }
4590: 0a 0a 20 20 20 20 20 20 20 20 66 6f 72 20 28 69  ..        for (i
45a0: 6e 74 20 69 20 3d 20 30 3b 20 69 20 3c 20 35 3b  nt i = 0; i < 5;
45b0: 20 69 2b 2b 29 20 7b 0a 20 20 20 20 20 20 20 20   i++) {.        
45c0: 20 20 20 20 66 69 6e 61 6c 20 43 61 6e 63 65 6c      final Cancel
45d0: 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20 63 61 6e  lationSignal can
45e0: 63 65 6c 6c 61 74 69 6f 6e 53 69 67 6e 61 6c 20  cellationSignal 
45f0: 3d 20 6e 65 77 20 43 61 6e 63 65 6c 6c 61 74 69  = new Cancellati
4600: 6f 6e 53 69 67 6e 61 6c 28 29 3b 0a 20 20 20 20  onSignal();.    
4610: 20 20 20 20 20 20 20 20 54 68 72 65 61 64 20 63          Thread c
4620: 61 6e 63 65 6c 6c 61 74 69 6f 6e 54 68 72 65 61  ancellationThrea
4630: 64 20 3d 20 6e 65 77 20 54 68 72 65 61 64 28 29  d = new Thread()
4640: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
4650: 20 20 20 40 4f 76 65 72 72 69 64 65 0a 20 20 20     @Override.   
4660: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 75 62               pub
4670: 6c 69 63 20 76 6f 69 64 20 72 75 6e 28 29 20 7b  lic void run() {
4680: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4690: 20 20 20 20 20 74 72 79 20 7b 0a 20 20 20 20 20       try {.     
46a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46b0: 20 20 20 54 68 72 65 61 64 2e 73 6c 65 65 70 28     Thread.sleep(
46c0: 33 30 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  300);.          
46d0: 20 20 20 20 20 20 20 20 20 20 7d 20 63 61 74 63            } catc
46e0: 68 20 28 49 6e 74 65 72 72 75 70 74 65 64 45 78  h (InterruptedEx
46f0: 63 65 70 74 69 6f 6e 20 65 78 29 20 7b 0a 20 20  ception ex) {.  
4700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4710: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
4720: 20 20 20 20 20 20 20 20 63 61 6e 63 65 6c 6c 61          cancella
4730: 74 69 6f 6e 53 69 67 6e 61 6c 2e 63 61 6e 63 65  tionSignal.cance
4740: 6c 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  l();.           
4750: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
4760: 20 20 20 7d 3b 0a 20 20 20 20 20 20 20 20 20 20     };.          
4770: 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20 20 20    try {.        
4780: 20 20 20 20 20 20 20 20 2f 2f 20 42 75 69 6c 64          // Build
4790: 20 61 6e 20 75 6e 73 61 74 69 73 66 69 61 62 6c   an unsatisfiabl
47a0: 65 20 35 2d 77 61 79 20 63 72 6f 73 73 2d 70 72  e 5-way cross-pr
47b0: 6f 64 75 63 74 20 71 75 65 72 79 20 6f 76 65 72  oduct query over
47c0: 20 31 30 30 20 76 61 6c 75 65 73 20 62 75 74 0a   100 values but.
47d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
47e0: 2f 2f 20 70 72 6f 64 75 63 65 73 20 6e 6f 20 6f  // produces no o
47f0: 75 74 70 75 74 2e 20 20 54 68 69 73 20 73 68 6f  utput.  This sho
4800: 75 6c 64 20 66 6f 72 63 65 20 53 51 4c 69 74 65  uld force SQLite
4810: 20 74 6f 20 6c 6f 6f 70 20 66 6f 72 20 61 20 6c   to loop for a l
4820: 6f 6e 67 20 74 69 6d 65 0a 20 20 20 20 20 20 20  ong time.       
4830: 20 20 20 20 20 20 20 20 20 2f 2f 20 61 73 20 69           // as i
4840: 74 20 74 65 73 74 73 20 31 30 5e 31 30 20 63 6f  t tests 10^10 co
4850: 6d 62 69 6e 61 74 69 6f 6e 73 2e 0a 20 20 20 20  mbinations..    
4860: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 69              SQLi
4870: 74 65 51 75 65 72 79 42 75 69 6c 64 65 72 20 73  teQueryBuilder s
4880: 71 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65  qliteQueryBuilde
4890: 72 20 3d 20 6e 65 77 20 53 51 4c 69 74 65 51 75  r = new SQLiteQu
48a0: 65 72 79 42 75 69 6c 64 65 72 28 29 3b 0a 20 20  eryBuilder();.  
48b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71                sq
48c0: 6c 69 74 65 51 75 65 72 79 42 75 69 6c 64 65 72  liteQueryBuilder
48d0: 2e 73 65 74 54 61 62 6c 65 73 28 22 78 20 41 53  .setTables("x AS
48e0: 20 61 2c 20 78 20 41 53 20 62 2c 20 78 20 41 53   a, x AS b, x AS
48f0: 20 63 2c 20 78 20 41 53 20 64 2c 20 78 20 41 53   c, x AS d, x AS
4900: 20 65 22 29 3b 0a 0a 20 20 20 20 20 20 20 20 20   e");..         
4910: 20 20 20 20 20 20 20 63 61 6e 63 65 6c 6c 61 74         cancellat
4920: 69 6f 6e 54 68 72 65 61 64 2e 73 74 61 72 74 28  ionThread.start(
4930: 29 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20  );..            
4940: 20 20 20 20 66 69 6e 61 6c 20 6c 6f 6e 67 20 73      final long s
4950: 74 61 72 74 54 69 6d 65 20 3d 20 53 79 73 74 65  tartTime = Syste
4960: 6d 2e 6e 61 6e 6f 54 69 6d 65 28 29 3b 0a 20 20  m.nanoTime();.  
4970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 72                tr
4980: 79 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  y {.            
4990: 20 20 20 20 20 20 20 20 43 75 72 73 6f 72 20 63          Cursor c
49a0: 75 72 73 6f 72 20 3d 20 73 71 6c 69 74 65 51 75  ursor = sqliteQu
49b0: 65 72 79 42 75 69 6c 64 65 72 2e 71 75 65 72 79  eryBuilder.query
49c0: 28 6d 44 61 74 61 62 61 73 65 2c 20 6e 75 6c 6c  (mDatabase, null
49d0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
49e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 61                "a
49f0: 2e 76 20 2b 20 62 2e 76 20 2b 20 63 2e 76 20 2b  .v + b.v + c.v +
4a00: 20 64 2e 76 20 2b 20 65 2e 76 20 3e 20 31 30 30   d.v + e.v > 100
4a10: 30 30 30 30 22 2c 0a 20 20 20 20 20 20 20 20 20  0000",.         
4a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a30: 20 20 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e     null, null, n
4a40: 75 6c 6c 2c 20 6e 75 6c 6c 2c 20 6e 75 6c 6c 2c  ull, null, null,
4a50: 20 63 61 6e 63 65 6c 6c 61 74 69 6f 6e 53 69 67   cancellationSig
4a60: 6e 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  nal);.          
4a70: 20 20 20 20 20 20 20 20 20 20 63 75 72 73 6f 72            cursor
4a80: 2e 67 65 74 43 6f 75 6e 74 28 29 3b 20 2f 2f 20  .getCount(); // 
4a90: 66 6f 72 63 65 20 65 78 65 63 75 74 69 6f 6e 0a  force execution.
4aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ab0: 20 20 20 20 66 61 69 6c 28 22 45 78 70 65 63 74      fail("Expect
4ac0: 65 64 20 4f 70 65 72 61 74 69 6f 6e 43 61 6e 63  ed OperationCanc
4ad0: 65 6c 65 64 45 78 63 65 70 74 69 6f 6e 22 29 3b  eledException");
4ae0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4af0: 20 7d 20 63 61 74 63 68 20 28 4f 70 65 72 61 74   } catch (Operat
4b00: 69 6f 6e 43 61 6e 63 65 6c 65 64 45 78 63 65 70  ionCanceledExcep
4b10: 74 69 6f 6e 20 65 78 29 20 7b 0a 20 20 20 20 20  tion ex) {.     
4b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4b30: 2f 20 65 78 70 65 63 74 65 64 0a 20 20 20 20 20  / expected.     
4b40: 20 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20             }..  
4b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2f                //
4b60: 20 57 65 20 77 61 6e 74 20 74 6f 20 63 6f 6e 66   We want to conf
4b70: 69 72 6d 20 74 68 61 74 20 74 68 65 20 71 75 65  irm that the que
4b80: 72 79 20 72 65 61 6c 6c 79 20 77 61 73 20 72 75  ry really was ru
4b90: 6e 6e 69 6e 67 20 61 6e 64 20 74 68 65 6e 20 67  nning and then g
4ba0: 6f 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ot.             
4bb0: 20 20 20 2f 2f 20 63 61 6e 63 65 6c 65 64 20 6d     // canceled m
4bc0: 69 64 77 61 79 2e 0a 20 20 20 20 20 20 20 20 20  idway..         
4bd0: 20 20 20 20 20 20 20 66 69 6e 61 6c 20 6c 6f 6e         final lon
4be0: 67 20 77 61 69 74 54 69 6d 65 20 3d 20 53 79 73  g waitTime = Sys
4bf0: 74 65 6d 2e 6e 61 6e 6f 54 69 6d 65 28 29 20 2d  tem.nanoTime() -
4c00: 20 73 74 61 72 74 54 69 6d 65 3b 0a 20 20 20 20   startTime;.    
4c10: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 28              if (
4c20: 77 61 69 74 54 69 6d 65 20 3e 20 31 35 30 20 2a  waitTime > 150 *
4c30: 20 31 30 30 30 30 30 30 4c 20 26 26 20 77 61 69   1000000L && wai
4c40: 74 54 69 6d 65 20 3c 20 36 30 30 20 2a 20 31 30  tTime < 600 * 10
4c50: 30 30 30 30 30 4c 29 20 7b 0a 20 20 20 20 20 20  00000L) {.      
4c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
4c70: 74 75 72 6e 3b 20 2f 2f 20 73 75 63 63 65 73 73  turn; // success
4c80: 21 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  !.              
4c90: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
4ca0: 7d 20 66 69 6e 61 6c 6c 79 20 7b 0a 20 20 20 20  } finally {.    
4cb0: 20 20 20 20 20 20 20 20 20 20 20 20 74 72 79 20              try 
4cc0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
4cd0: 20 20 20 20 20 20 63 61 6e 63 65 6c 6c 61 74 69        cancellati
4ce0: 6f 6e 54 68 72 65 61 64 2e 6a 6f 69 6e 28 29 3b  onThread.join();
4cf0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4d00: 20 7d 20 63 61 74 63 68 20 28 49 6e 74 65 72 72   } catch (Interr
4d10: 75 70 74 65 64 45 78 63 65 70 74 69 6f 6e 20 65  uptedException e
4d20: 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) {.            
4d30: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
4d40: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20    }.        }.. 
4d50: 20 20 20 20 20 20 20 2f 2f 20 4f 63 63 61 73 69         // Occasi
4d60: 6f 6e 61 6c 6c 79 20 77 65 20 6d 69 67 68 74 20  onally we might 
4d70: 6d 69 73 73 20 74 68 65 20 74 69 6d 69 6e 67 20  miss the timing 
4d80: 64 65 61 64 6c 69 6e 65 20 64 75 65 20 74 6f 20  deadline due to 
4d90: 66 61 63 74 6f 72 73 20 69 6e 20 74 68 65 0a 20  factors in the. 
4da0: 20 20 20 20 20 20 20 2f 2f 20 65 6e 76 69 72 6f         // enviro
4db0: 6e 6d 65 6e 74 2c 20 62 75 74 20 69 66 20 61 66  nment, but if af
4dc0: 74 65 72 20 73 65 76 65 72 61 6c 20 74 72 69 61  ter several tria
4dd0: 6c 73 20 77 65 20 73 74 69 6c 6c 20 63 6f 75 6c  ls we still coul
4de0: 64 6e 27 74 20 64 65 6d 6f 6e 73 74 72 61 74 65  dn't demonstrate
4df0: 0a 20 20 20 20 20 20 20 20 2f 2f 20 74 68 61 74  .        // that
4e00: 20 74 68 65 20 71 75 65 72 79 20 77 61 73 20 63   the query was c
4e10: 61 6e 63 65 6c 65 64 2c 20 74 68 65 6e 20 74 68  anceled, then th
4e20: 65 20 74 65 73 74 20 6d 75 73 74 20 62 65 20 62  e test must be b
4e30: 72 6f 6b 65 6e 2e 0a 20 20 20 20 20 20 20 20 66  roken..        f
4e40: 61 69 6c 28 22 43 6f 75 6c 64 20 6e 6f 74 20 70  ail("Could not p
4e50: 72 6f 76 65 20 74 68 61 74 20 74 68 65 20 71 75  rove that the qu
4e60: 65 72 79 20 61 63 74 75 61 6c 6c 79 20 63 61 6e  ery actually can
4e70: 63 65 6c 65 64 20 6d 69 64 77 61 79 20 64 75 72  celed midway dur
4e80: 69 6e 67 20 65 78 65 63 75 74 69 6f 6e 2e 22 29  ing execution.")
4e90: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 72 69  ;.    }..    pri
4ea0: 76 61 74 65 20 76 6f 69 64 20 63 72 65 61 74 65  vate void create
4eb0: 45 6d 70 6c 6f 79 65 65 54 61 62 6c 65 28 29 20  EmployeeTable() 
4ec0: 7b 0a 20 20 20 20 20 20 20 20 6d 44 61 74 61 62  {.        mDatab
4ed0: 61 73 65 2e 65 78 65 63 53 51 4c 28 22 43 52 45  ase.execSQL("CRE
4ee0: 41 54 45 20 54 41 42 4c 45 20 65 6d 70 6c 6f 79  ATE TABLE employ
4ef0: 65 65 20 28 5f 69 64 20 49 4e 54 45 47 45 52 20  ee (_id INTEGER 
4f00: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 22 20 2b  PRIMARY KEY, " +
4f10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4f20: 20 22 6e 61 6d 65 20 54 45 58 54 2c 20 6d 6f 6e   "name TEXT, mon
4f30: 74 68 20 49 4e 54 45 47 45 52 2c 20 73 61 6c 61  th INTEGER, sala
4f40: 72 79 20 49 4e 54 45 47 45 52 29 3b 22 29 3b 0a  ry INTEGER);");.
4f50: 20 20 20 20 20 20 20 20 6d 44 61 74 61 62 61 73          mDatabas
4f60: 65 2e 65 78 65 63 53 51 4c 28 22 49 4e 53 45 52  e.execSQL("INSER
4f70: 54 20 49 4e 54 4f 20 65 6d 70 6c 6f 79 65 65 20  T INTO employee 
4f80: 28 6e 61 6d 65 2c 20 6d 6f 6e 74 68 2c 20 73 61  (name, month, sa
4f90: 6c 61 72 79 29 20 22 20 2b 0a 20 20 20 20 20 20  lary) " +.      
4fa0: 20 20 20 20 20 20 20 20 20 20 22 56 41 4c 55 45            "VALUE
4fb0: 53 20 28 27 4d 69 6b 65 27 2c 20 27 31 27 2c 20  S ('Mike', '1', 
4fc0: 27 31 30 30 30 27 29 3b 22 29 3b 0a 20 20 20 20  '1000');");.    
4fd0: 20 20 20 20 6d 44 61 74 61 62 61 73 65 2e 65 78      mDatabase.ex
4fe0: 65 63 53 51 4c 28 22 49 4e 53 45 52 54 20 49 4e  ecSQL("INSERT IN
4ff0: 54 4f 20 65 6d 70 6c 6f 79 65 65 20 28 6e 61 6d  TO employee (nam
5000: 65 2c 20 6d 6f 6e 74 68 2c 20 73 61 6c 61 72 79  e, month, salary
5010: 29 20 22 20 2b 0a 20 20 20 20 20 20 20 20 20 20  ) " +.          
5020: 20 20 20 20 20 20 22 56 41 4c 55 45 53 20 28 27        "VALUES ('
5030: 4d 69 6b 65 27 2c 20 27 32 27 2c 20 27 33 30 30  Mike', '2', '300
5040: 30 27 29 3b 22 29 3b 0a 20 20 20 20 20 20 20 20  0');");.        
5050: 6d 44 61 74 61 62 61 73 65 2e 65 78 65 63 53 51  mDatabase.execSQ
5060: 4c 28 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 65  L("INSERT INTO e
5070: 6d 70 6c 6f 79 65 65 20 28 6e 61 6d 65 2c 20 6d  mployee (name, m
5080: 6f 6e 74 68 2c 20 73 61 6c 61 72 79 29 20 22 20  onth, salary) " 
5090: 2b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  +.              
50a0: 20 20 22 56 41 4c 55 45 53 20 28 27 6a 61 63 6b    "VALUES ('jack
50b0: 27 2c 20 27 31 27 2c 20 27 32 30 30 30 27 29 3b  ', '1', '2000');
50c0: 22 29 3b 0a 20 20 20 20 20 20 20 20 6d 44 61 74  ");.        mDat
50d0: 61 62 61 73 65 2e 65 78 65 63 53 51 4c 28 22 49  abase.execSQL("I
50e0: 4e 53 45 52 54 20 49 4e 54 4f 20 65 6d 70 6c 6f  NSERT INTO emplo
50f0: 79 65 65 20 28 6e 61 6d 65 2c 20 6d 6f 6e 74 68  yee (name, month
5100: 2c 20 73 61 6c 61 72 79 29 20 22 20 2b 0a 20 20  , salary) " +.  
5110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 56                "V
5120: 41 4c 55 45 53 20 28 27 6a 61 63 6b 27 2c 20 27  ALUES ('jack', '
5130: 33 27 2c 20 27 31 35 30 30 27 29 3b 22 29 3b 0a  3', '1500');");.
5140: 20 20 20 20 20 20 20 20 6d 44 61 74 61 62 61 73          mDatabas
5150: 65 2e 65 78 65 63 53 51 4c 28 22 49 4e 53 45 52  e.execSQL("INSER
5160: 54 20 49 4e 54 4f 20 65 6d 70 6c 6f 79 65 65 20  T INTO employee 
5170: 28 6e 61 6d 65 2c 20 6d 6f 6e 74 68 2c 20 73 61  (name, month, sa
5180: 6c 61 72 79 29 20 22 20 2b 0a 20 20 20 20 20 20  lary) " +.      
5190: 20 20 20 20 20 20 20 20 20 20 22 56 41 4c 55 45            "VALUE
51a0: 53 20 28 27 4a 69 6d 27 2c 20 27 31 27 2c 20 27  S ('Jim', '1', '
51b0: 31 30 30 30 27 29 3b 22 29 3b 0a 20 20 20 20 20  1000');");.     
51c0: 20 20 20 6d 44 61 74 61 62 61 73 65 2e 65 78 65     mDatabase.exe
51d0: 63 53 51 4c 28 22 49 4e 53 45 52 54 20 49 4e 54  cSQL("INSERT INT
51e0: 4f 20 65 6d 70 6c 6f 79 65 65 20 28 6e 61 6d 65  O employee (name
51f0: 2c 20 6d 6f 6e 74 68 2c 20 73 61 6c 61 72 79 29  , month, salary)
5200: 20 22 20 2b 0a 20 20 20 20 20 20 20 20 20 20 20   " +.           
5210: 20 20 20 20 20 22 56 41 4c 55 45 53 20 28 27 4a       "VALUES ('J
5220: 69 6d 27 2c 20 27 33 27 2c 20 27 33 35 30 30 27  im', '3', '3500'
5230: 29 3b 22 29 3b 0a 20 20 20 20 7d 0a 7d 0a        );");.    }.}.