1 package com.xtremelabs.robolectric.shadows;
2 
3 import android.database.sqlite.SQLiteDatabase;
4 import android.database.sqlite.SQLiteProgram;
5 import com.xtremelabs.robolectric.Robolectric;
6 import com.xtremelabs.robolectric.internal.Implementation;
7 import com.xtremelabs.robolectric.internal.Implements;
8 import com.xtremelabs.robolectric.internal.RealObject;
9 
10 import java.sql.Connection;
11 import java.sql.PreparedStatement;
12 import java.sql.SQLException;
13 import java.sql.Statement;
14 
15 @Implements(SQLiteProgram.class)
16 public abstract class ShadowSQLiteProgram {
17 	@RealObject	SQLiteProgram realSQLiteProgram;
18 	protected SQLiteDatabase mDatabase;
19 	Connection connection;
20 	PreparedStatement actualDBstatement;
init(SQLiteDatabase db, String sql)21 	public void init(SQLiteDatabase db, String sql) {
22 	 mDatabase = db;
23 	 connection = Robolectric.shadowOf(db).getConnection();
24 
25 	 try {
26 			actualDBstatement = connection.prepareStatement(sql,
27 					Statement.RETURN_GENERATED_KEYS);
28 		} catch (SQLException e) {
29 			throw new RuntimeException(e);
30 		}
31 	}
32 
33     /**
34      * Bind a NULL value to this statement. The value remains bound until
35      * {@link #clearBindings} is called.
36      *
37      * @param index The 1-based index to the parameter to bind null to
38      */
39 	@Implementation
bindNull(int index)40     public void bindNull(int index) {
41 		checkDatabaseIsOpen();
42 		try {
43 			// SQLite ignores typecode
44 			// typecode is also ignored in H2 when using the two parameter setNUll()
45 			actualDBstatement.setNull(index,java.sql.Types.NULL);
46 		} catch (SQLException e) {
47 			throw new RuntimeException(e);
48 		}
49     }
50 
51     /**
52      * Bind a long value to this statement. The value remains bound until
53      * {@link #clearBindings} is called.
54      *
55      * @param index The 1-based index to the parameter to bind
56      * @param value The value to bind
57      */
58     @Implementation
bindLong(int index, long value)59     public void bindLong(int index, long value) {
60     	checkDatabaseIsOpen();
61 
62     	try {
63 			actualDBstatement.setLong(index,value);
64 		} catch (SQLException e) {
65 			throw new RuntimeException(e);
66 		}
67     }
68 
checkDatabaseIsOpen()69     private void checkDatabaseIsOpen() {
70     	if (!mDatabase.isOpen()) {
71             throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
72         }
73     }
74 
getStatement()75     public PreparedStatement getStatement() {
76     	return actualDBstatement;
77     }
78 
79     /**
80      * Bind a double value to this statement. The value remains bound until
81      * {@link #clearBindings} is called.
82      *
83      * @param index The 1-based index to the parameter to bind
84      * @param value The value to bind
85      */
86     @Implementation
bindDouble(int index, double value)87     public void bindDouble(int index, double value) {
88     	checkDatabaseIsOpen();
89     	try {
90 			actualDBstatement.setDouble(index,value);
91 		} catch (SQLException e) {
92 			throw new RuntimeException(e);
93 		}
94     }
95 
96     /**
97      * Bind a String value to this statement. The value remains bound until
98      * {@link #clearBindings} is called.
99      *
100      * @param index The 1-based index to the parameter to bind
101      * @param value The value to bind
102      */
103     @Implementation
bindString(int index, String value)104     public void bindString(int index, String value) {
105         if (value == null) {
106             throw new IllegalArgumentException("the bind value at index " + index + " is null");
107         }
108         checkDatabaseIsOpen();
109         try {
110 			actualDBstatement.setString(index,value);
111 		} catch (SQLException e) {
112 			throw new RuntimeException(e);
113 		}
114     }
115 
116     /**
117      * Bind a byte array value to this statement. The value remains bound until
118      * {@link #clearBindings} is called.
119      *
120      * @param index The 1-based index to the parameter to bind
121      * @param value The value to bind
122      */
123     @Implementation
bindBlob(int index, byte[] value)124     public void bindBlob(int index, byte[] value) {
125         if (value == null) {
126             throw new IllegalArgumentException("the bind value at index " + index + " is null");
127         }
128         checkDatabaseIsOpen();
129         try {
130 			actualDBstatement.setBytes(index,value);
131 		} catch (SQLException e) {
132 			throw new RuntimeException(e);
133 		}
134 
135     }
136 
137     /**
138      * Clears all existing bindings. Unset bindings are treated as NULL.
139      */
140     @Implementation
clearBindings()141     public void clearBindings() {
142     	checkDatabaseIsOpen();
143 
144     	try {
145 			actualDBstatement.clearParameters();
146 		} catch (SQLException e) {
147 			throw new RuntimeException(e);
148 		}
149     }
150 }
151