1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package groovy.sql;
47
48 import groovy.lang.Closure;
49 import groovy.lang.GroovyRuntimeException;
50
51 import java.sql.Connection;
52 import java.sql.PreparedStatement;
53 import java.sql.SQLException;
54 import java.util.ArrayList;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.logging.Level;
59
60 import org.codehaus.groovy.ast.ClassNode;
61 import org.codehaus.groovy.ast.MethodNode;
62 import org.codehaus.groovy.ast.stmt.Statement;
63
64 /***
65 * Represents an extent of objects
66 *
67 * @author Chris Stevenson
68 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
69 * @version $Revision: 1.8 $
70 */
71 public class DataSet extends Sql {
72
73 private Closure where;
74 private DataSet parent;
75 private String table;
76 private SqlWhereVisitor visitor;
77 private String sql;
78 private List params;
79
80 public DataSet(Sql sql, Class type) {
81 super(sql);
82 String table = type.getName();
83 int idx = table.lastIndexOf('.');
84 if (idx > 0) {
85 table = table.substring(idx + 1);
86 }
87 this.table = table.toLowerCase();
88 }
89
90 public DataSet(Sql sql, String table) {
91 super(sql);
92 this.table = table;
93 }
94
95 public DataSet(DataSet parent, Closure where) {
96 super(parent);
97 this.table = parent.table;
98 this.parent = parent;
99 this.where = where;
100 }
101
102 public void add(Map values) throws SQLException {
103 StringBuffer buffer = new StringBuffer("insert into ");
104 buffer.append(table);
105 buffer.append(" (");
106 StringBuffer paramBuffer = new StringBuffer();
107 boolean first = true;
108 for (Iterator iter = values.entrySet().iterator(); iter.hasNext();) {
109 Map.Entry entry = (Map.Entry) iter.next();
110 String column = entry.getKey().toString();
111 if (first) {
112 first = false;
113 paramBuffer.append("?");
114 }
115 else {
116 buffer.append(", ");
117 paramBuffer.append(", ?");
118 }
119 buffer.append(column);
120 }
121 buffer.append(") values (");
122 buffer.append(paramBuffer.toString());
123 buffer.append(")");
124
125 Connection connection = createConnection();
126 PreparedStatement statement = null;
127 try {
128 statement = connection.prepareStatement(buffer.toString());
129 int i = 1;
130 for (Iterator iter = values.entrySet().iterator(); iter.hasNext();) {
131 Map.Entry entry = (Map.Entry) iter.next();
132 setObject(statement, i++, entry.getValue());
133 }
134 int answer = statement.executeUpdate();
135 if (answer != 1) {
136 log.log(Level.WARNING, "Should have updated 1 row not " + answer + " when trying to add: " + values);
137 }
138 }
139 catch (SQLException e) {
140 log.log(Level.WARNING, "Failed to add row for: " + values, e);
141 throw e;
142 }
143 finally {
144 closeResources(connection, statement);
145 }
146 }
147
148 public DataSet findAll(Closure where) {
149 return new DataSet(this, where);
150 }
151
152 public void each(Closure closure) throws SQLException {
153 eachRow(getSql(), getParameters(), closure);
154 }
155
156 public String getSql() {
157 if (sql == null) {
158 sql = "select * from " + table;
159 if (where != null) {
160 String clause = "";
161 if (parent != null && parent.where != null) {
162 clause += parent.getSqlVisitor().getWhere() + " and ";
163 }
164 clause += getSqlVisitor().getWhere();
165 if (clause.length() > 0) {
166 sql += " where " + clause;
167 }
168 }
169 }
170 return sql;
171 }
172
173 public List getParameters() {
174 if (params == null) {
175 params = new ArrayList();
176 if (parent != null && parent.where != null) {
177 params.addAll(parent.getParameters());
178 }
179 params.addAll(getSqlVisitor().getParameters());
180 }
181 return params;
182 }
183
184 protected SqlWhereVisitor getSqlVisitor() {
185 if (visitor == null) {
186 visitor = new SqlWhereVisitor();
187 if (where != null) {
188 ClassNode classNode = where.getMetaClass().getClassNode();
189 if (classNode == null) {
190 throw new GroovyRuntimeException(
191 "Could not find the ClassNode for MetaClass: " + where.getMetaClass());
192 }
193 List methods = classNode.getDeclaredMethods("doCall");
194 if (!methods.isEmpty()) {
195 MethodNode method = (MethodNode) methods.get(0);
196 if (method != null) {
197 Statement statement = method.getCode();
198 if (statement != null) {
199 statement.visit(visitor);
200 }
201 }
202 }
203 }
204 }
205 return visitor;
206 }
207
208
209
210 public DataSet createView(Closure criteria) {
211 return new DataSet(this, criteria);
212 }
213 }