- circumvented the JDBC ?-bug
[mir.git] / source / mircoders / storage / DatabaseLinksImcs.java
1 /*\r
2  * Copyright (C) 2001, 2002  The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\r
6  * Mir is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Mir is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with Mir; if not, write to the Free Software\r
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19  *\r
20  * In addition, as a special exception, The Mir-coders gives permission to link\r
21  * the code of this program with the com.oreilly.servlet library, any library\r
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced\r
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of\r
24  * the above that use the same license as the above), and distribute linked\r
25  * combinations including the two.  You must obey the GNU General Public\r
26  * License in all respects for all of the code used other than the above\r
27  * mentioned libraries.  If you modify this file, you may extend this exception\r
28  * to your version of the file, but you are not obligated to do so.  If you do\r
29  * not wish to do so, delete this exception statement from your version.\r
30  */\r
31 \r
32 package  mircoders.storage;\r
33 \r
34 import  java.lang.*;\r
35 import  java.sql.*;\r
36 import  java.io.*;\r
37 import  java.util.*;\r
38 import  freemarker.template.*;\r
39 import  mir.storage.*;\r
40 import  mir.entity.*;\r
41 import  mir.misc.*;\r
42 import  mir.util.*;\r
43 \r
44 \r
45 /**\r
46  * <b>Diese Klasse implementiert die Datenbankverbindung zur MetaObjekt-Tabelle\r
47  *\r
48  *\r
49  */\r
50 public class DatabaseLinksImcs extends Database\r
51     implements StorageObject {\r
52   private static DatabaseLinksImcs instance;\r
53 \r
54   /**\r
55    * put your documentation comment here\r
56    * @return\r
57    * @exception StorageObjectException\r
58    */\r
59   // the following *has* to be sychronized cause this static method\r
60   // could get preemted and we could end up with 2 instances of DatabaseFoo..\r
61   // see the "Singletons with needles and thread" article at JavaWorld -mh\r
62   public synchronized static DatabaseLinksImcs getInstance() throws\r
63       StorageObjectException {\r
64     if (instance == null) {\r
65       instance = new DatabaseLinksImcs();\r
66       instance.myselfDatabase = instance;\r
67     }\r
68     return instance;\r
69   }\r
70 \r
71   /**\r
72    * put your documentation comment here\r
73    */\r
74   private DatabaseLinksImcs() throws StorageObjectException {\r
75     super();\r
76     ////this.cache = new HashMap();\r
77     this.hasTimestamp = false;\r
78     this.theTable = "links_imcs";\r
79     try {\r
80       this.theEntityClass = Class.forName("mircoders.entity.EntityLinksImcs");\r
81     }\r
82     catch (Exception e) {\r
83       throw new StorageObjectException(e.toString());\r
84     }\r
85   }\r
86 \r
87   /** @todo toooo much copy/paste in this class //rk  */\r
88 \r
89   public String insert(Entity theEntity) throws StorageObjectException {\r
90     String returnId = "0";\r
91     Connection con = null;\r
92     PreparedStatement pstmt = null;\r
93     //cache\r
94     invalidatePopupCache();\r
95     try {\r
96       HashMap theEntityValues = theEntity.getValues();\r
97       ArrayList streamedInput = theEntity.streamedInput();\r
98       StringBuffer f = new StringBuffer();\r
99       StringBuffer v = new StringBuffer();\r
100       String aField, aValue;\r
101       boolean firstField = true;\r
102       // make sql-string\r
103       for (int i = 0; i < getFields().size(); i++) {\r
104         aField = (String) getFields().get(i);\r
105         if (!aField.equals(thePKeyName)) {\r
106           aValue = null;\r
107           // sonderfaelle\r
108           if (aField.equals("webdb_create")) {\r
109             aValue = "NOW()";\r
110           }\r
111           else {\r
112             if (streamedInput != null && streamedInput.contains(aField)) {\r
113               aValue = "?";\r
114             }\r
115             else {\r
116               if (theEntityValues.containsKey(aField)) {\r
117                 if (aField.equals("to_parent_id")) {\r
118                   aValue = JDBCStringRoutines.escapeStringLiteral((String) theEntityValues.get(aField));\r
119                 }\r
120                 else {\r
121                   aValue = "'" + JDBCStringRoutines.escapeStringLiteral((String) theEntityValues.get(aField)) +  "'";\r
122                 }\r
123               }\r
124             }\r
125           }\r
126           // wenn Wert gegeben, dann einbauen\r
127           if (aValue != null) {\r
128             if (firstField == false) {\r
129               f.append(",");\r
130               v.append(",");\r
131             }\r
132             else {\r
133               firstField = false;\r
134             }\r
135             f.append(aField);\r
136             v.append(aValue);\r
137           }\r
138         }\r
139       } // end for\r
140       // insert into db\r
141       StringBuffer sqlBuf = new StringBuffer("insert into ").append(theTable).\r
142           append("(").append(f).append(") values (").append(v).append(")");\r
143       String sql = sqlBuf.toString();\r
144       theLog.printInfo("INSERT: " + sql);\r
145       con = getPooledCon();\r
146       con.setAutoCommit(false);\r
147       pstmt = con.prepareStatement(sql);\r
148       if (streamedInput != null) {\r
149         for (int i = 0; i < streamedInput.size(); i++) {\r
150           String inputString = (String) theEntityValues.get(streamedInput.get(i));\r
151           pstmt.setBytes(i + 1, inputString.getBytes());\r
152         }\r
153       }\r
154       pstmt.execute();\r
155       pstmt = con.prepareStatement(theAdaptor.getLastInsertSQL( (Database)\r
156           myselfDatabase));\r
157       ResultSet rs = pstmt.executeQuery();\r
158       rs.next();\r
159       returnId = rs.getString(1);\r
160       theEntity.setId(returnId);\r
161     }\r
162     catch (SQLException sqe) {\r
163       throwSQLException(sqe, "insert");\r
164     }\r
165     finally {\r
166       try {\r
167         con.setAutoCommit(true);\r
168       }\r
169       catch (Exception e) {\r
170         ;\r
171       }\r
172       freeConnection(con, pstmt);\r
173     }\r
174     return returnId;\r
175   }\r
176 \r
177   public void update(Entity theEntity) throws StorageObjectException {\r
178     Connection con = null;\r
179     PreparedStatement pstmt = null;\r
180     ArrayList streamedInput = theEntity.streamedInput();\r
181     HashMap theEntityValues = theEntity.getValues();\r
182     String id = theEntity.getId();\r
183     String aField;\r
184     StringBuffer fv = new StringBuffer();\r
185     boolean firstField = true;\r
186     //cache\r
187     invalidatePopupCache();\r
188     // build sql statement\r
189     for (int i = 0; i < getFields().size(); i++) {\r
190       aField = (String) metadataFields.get(i);\r
191       // only normal cases\r
192       if (! (aField.equals(thePKeyName) || aField.equals("webdb_create") ||\r
193              aField.equals("webdb_lastchange") ||\r
194              (streamedInput != null && streamedInput.contains(aField)))) {\r
195         if (theEntityValues.containsKey(aField)) {\r
196           if (firstField == false) {\r
197             fv.append(", ");\r
198           }\r
199           else {\r
200             firstField = false;\r
201           }\r
202           if (aField.equals("to_parent_id")) {\r
203             fv.append(aField).append("=").append(JDBCStringRoutines.escapeStringLiteral((String)theEntityValues.get(aField)));\r
204           }\r
205           else {\r
206             fv.append(aField).append("='").append(JDBCStringRoutines.escapeStringLiteral((String)theEntityValues.get(aField))).append("'");\r
207           }\r
208         }\r
209       }\r
210     }\r
211     StringBuffer sql = new StringBuffer("update ").append(theTable).append(\r
212         " set ").append(fv);\r
213     // exceptions\r
214     if (metadataFields.contains("webdb_lastchange")) {\r
215       sql.append(",webdb_lastchange=NOW()");\r
216     }\r
217     if (streamedInput != null) {\r
218       for (int i = 0; i < streamedInput.size(); i++) {\r
219         sql.append(",").append(streamedInput.get(i)).append("=?");\r
220       }\r
221     }\r
222     sql.append(" where id=").append(id);\r
223     theLog.printInfo("UPDATE: " + sql);\r
224     // execute sql\r
225     try {\r
226       con = getPooledCon();\r
227       con.setAutoCommit(false);\r
228       pstmt = con.prepareStatement(sql.toString());\r
229       if (streamedInput != null) {\r
230         for (int i = 0; i < streamedInput.size(); i++) {\r
231           String inputString = (String) theEntityValues.get(streamedInput.get(i));\r
232           pstmt.setBytes(i + 1, inputString.getBytes());\r
233         }\r
234       }\r
235       pstmt.executeUpdate();\r
236     }\r
237     catch (SQLException sqe) {\r
238       throwSQLException(sqe, "update");\r
239     }\r
240     finally {\r
241       try {\r
242         con.setAutoCommit(true);\r
243       }\r
244       catch (Exception e) {\r
245         ;\r
246       }\r
247       freeConnection(con, pstmt);\r
248     }\r
249   }\r
250 \r
251 }