Project

General

Profile

1
package edu.ucsb.nceas.metacat.admin.upgrade;
2
/**
3
 *  '$RCSfile$'
4
 *    Purpose: A Class for upgrading the database to version 1.5
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Saurabh Garg
8
 *
9
 *   '$Author: leinfelder $'
10
 *     '$Date: 2011-03-29 18:23:38 +0000 (Tue, 29 Mar 2011) $'
11
 * '$Revision: 6025 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28

    
29
import java.sql.Connection;
30
import java.sql.Driver;
31
import java.sql.ResultSet;
32
import java.sql.PreparedStatement;
33
import java.sql.SQLException;
34
import java.sql.Statement;
35
import java.sql.DriverManager;
36
import java.sql.Timestamp;
37
import java.util.Calendar;
38
import java.util.Map;
39
import java.util.TreeMap;
40

    
41
import javax.xml.bind.DatatypeConverter;
42

    
43
import org.apache.commons.logging.Log;
44
import org.apache.commons.logging.LogFactory;
45

    
46
import edu.ucsb.nceas.metacat.admin.AdminException;
47
import edu.ucsb.nceas.metacat.properties.PropertyService;
48
import edu.ucsb.nceas.utilities.SortedProperties;
49

    
50
public class UpgradeNodeDataDatetime implements UpgradeUtilityInterface {
51

    
52
	protected static Log log = LogFactory.getLog(UpgradeNodeDataDatetime.class);
53
	
54
    private String driver = null;
55
    private String url = null;
56
    private String user = null;
57
    private String password = null;
58

    
59
    public boolean upgrade() throws AdminException {
60
    	String[] tablesToUpdate = {"xml_nodes", "xml_nodes_revisions", "xml_path_index"};
61
        boolean success = true;
62
    	// update each table that needs updating
63
        try {
64
	        for (String tableName: tablesToUpdate) {
65
	        	success = success && upgradeSingleTable(tableName);
66
	        }
67
    	} catch (Exception e) {
68
			AdminException ae = new AdminException("Error upgrading tables: " + e.getMessage());
69
			ae.initCause(e);
70
			throw ae;
71
		}
72
    	
73
        return success;
74
    }
75
    
76
    /**
77
     * Utility method to retrieve a connection
78
     * @return db connection based on metacat configuration
79
     * @throws AdminException
80
     */
81
    private Connection getConnection() throws AdminException {
82

    
83
    	Connection conn = null;
84
    	try {
85
	    	// get the properties
86
			driver = PropertyService.getProperty("database.driver");
87
		    url = PropertyService.getProperty("database.connectionURI");
88
		    user = PropertyService.getProperty("database.user");
89
		    password = PropertyService.getProperty("database.password");
90
		    
91
	        // Create a JDBC connection to the database    	
92
	        Driver d = (Driver) Class.forName(driver).newInstance();
93
	        DriverManager.registerDriver(d);
94
	        conn = DriverManager.getConnection(url, user, password);
95
    	} catch (Exception e) {
96
			String msg = "Could not get connection: " + e.getMessage();
97
			log.error(msg);
98
			AdminException ae = new AdminException(msg);
99
			ae.initCause(e);
100
			throw ae;
101
		} 
102
    	return conn;
103
    	
104
    }
105
    
106
    /**
107
     * Look up the node data values that need converting to datetime fields
108
     * @param tableName
109
     * @return
110
     * @throws AdminException
111
     */
112
    private Map<String, Timestamp> getDataValues(String tableName) throws AdminException {
113
    	
114
		Map<String, Timestamp> dataValues = new TreeMap<String, Timestamp>();
115

    
116
    	try {
117
    		
118
        	Connection conn = getConnection();
119
	        
120
	        Statement sqlStatement = null;
121
	        ResultSet rset = null;
122
	        String nodeid = null;
123
            String nodedata = null;
124
            int count = 0;
125

    
126
			// select the nodes that are not null and look like dates
127
	        sqlStatement = conn .createStatement();
128
	        rset = sqlStatement.executeQuery(
129
	            "SELECT DISTINCT NODEID, NODEDATA "
130
	            + "FROM " + tableName
131
	            + " WHERE nodedata IS NOT NULL "
132
	            + " AND nodedata LIKE '____-__-__%' "
133
	            );
134
	
135
	        count = 0;
136
	        while (rset.next()) {
137
	
138
	            nodeid = rset.getString(1);
139
	            nodedata = rset.getString(2);
140
	
141
	            if (!nodedata.trim().equals("")) {
142
	            	try {
143
	            		Calendar dataDateValue = DatatypeConverter.parseDateTime(nodedata);
144
	                    Timestamp dataTimestamp = new Timestamp(dataDateValue.getTimeInMillis());
145
	                    dataValues.put(nodeid, dataTimestamp);
146
	                    log.debug("parsed: " + nodedata);
147
	                    count++;
148
	                    if (count%5 == 0) {
149
	                        log.debug(count + "...");
150
	                    }	
151
	            	} catch (Exception e) {
152
						// probably not a valid date
153
	            		continue;
154
					}
155
	            }              
156
	        }
157
	        log.warn("Converting table: " + tableName + " with " + count + " values found.");
158
	        rset.close();
159
	        sqlStatement.close();
160
	        conn.close();
161
    	} catch (Exception e) {
162
    		String msg = "Error parsing date time node data: " + e.getMessage();
163
    		log.error(msg, e);
164
            throw new AdminException(msg);
165
        }
166
    	return dataValues;
167
    }
168
    
169
    /**
170
     * Upgrade the nodedata fields that have datetime values in them
171
     * @param tableName the table that should be upgraded
172
     * @return
173
     * @throws Exception
174
     */
175
    private boolean upgradeSingleTable(String tableName) throws Exception {
176
    	
177
    	Map<String, Timestamp> dataValues = getDataValues(tableName);
178
    	
179
    	// get the connection
180
    	Connection conn = getConnection();
181
    	
182
    	// prepare a reusable statement
183
    	PreparedStatement pstmt = conn.prepareStatement(
184
                "update " + tableName +
185
                " set nodedatadate = ? " +
186
                " where nodeid = ? ");
187
    	
188
    	// update each value
189
    	for (String nodeid: dataValues.keySet()) {
190
    		Timestamp dataTimestamp = dataValues.get(nodeid);			
191
            pstmt.setTimestamp(1, dataTimestamp);
192
            pstmt.setInt(2, Integer.valueOf(nodeid));
193
            log.debug("Updating values: " + pstmt.toString());
194
            try {
195
            	pstmt.execute();
196
            } catch (SQLException sqle) {
197
				// probably too large a date
198
            	log.warn("DB error when updating date value, likely can ignore as some errors are to be expected. " + sqle.getMessage());
199
            	continue;
200
			}
201
    	}
202
    	
203
    	// clean up
204
    	if (conn != null) {
205
    		conn.close();
206
    	}
207
    	
208
    	return true;
209
    	
210
    }
211

    
212
    public static void main(String [] ags){
213

    
214
        try {
215
        	// set up the properties based on the test/deployed configuration of the workspace
216
        	SortedProperties testProperties = 
217
				new SortedProperties("test/test.properties");
218
			testProperties.load();
219
			String metacatContextDir = testProperties.getProperty("metacat.contextDir");
220
			PropertyService.getInstance(metacatContextDir + "/WEB-INF");
221
			// now run it
222
            UpgradeNodeDataDatetime upgrader = new UpgradeNodeDataDatetime();
223
	        upgrader.upgrade();
224
	        
225
	        // test the converter
226
            //Calendar date = DatatypeConverter.parseDate("2011-03-17");
227
            //System.out.println("date:" + DatatypeConverter.printDate(date));
228
            
229
        } catch (Exception ex) {
230
            System.out.println("Exception:" + ex.getMessage());
231
            ex.printStackTrace();
232
        }
233
    }
234
}
(7-7/8)