Project

General

Profile

Revision 6012

add support for temporal element query in pathquery
http://bugzilla.ecoinformatics.org/show_bug.cgi?id=2084

View differences:

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

  
27

  
28
import java.io.*;
29
import java.sql.Connection;
30
import java.sql.ResultSet;
31
import java.sql.PreparedStatement;
32
import java.sql.Statement;
33
import java.sql.SQLException;
34
import java.sql.DriverManager;
35

  
36
import edu.ucsb.nceas.metacat.properties.PropertyService;
37
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
38

  
39
public class upgrade_db_to_1_5{
40

  
41
    static String database = null;
42
    static String url = null;
43
    static String user = null;
44
    static String password = null;
45
    static {
46
    	try {
47
    	    database = PropertyService.getProperty("database.type");
48
    	    url = PropertyService.getProperty("database.connectionURI");
49
    	    user = PropertyService.getProperty("database.user");
50
    	    password = PropertyService.getProperty("database.password");
51
    	} catch (PropertyNotFoundException pnfe) {
52
            System.err.println("Error in upgrade_db_to_1_5 static block:"
53
                    + pnfe.getMessage());
54
            pnfe.printStackTrace();
55
    	}
56
     }
57

  
58
    public static void upgrade_xml_nodes(Connection sqlca) throws SQLException{
59
        Statement sqlStatement = null;
60
        PreparedStatement pstmt = null;
61
        ResultSet rset = null;
62

  
63
        // Delete old nodedatanumerical column from xml_nodes if one exsists
64
        try {
65
            System.out.println(
66
                "Deleting old nodedatanumerical column from xml_nodes...");
67

  
68
            pstmt = sqlca.prepareStatement(
69
                "ALTER TABLE xml_nodes DROP COLUMN nodedatanumerical");
70
            pstmt.execute();
71
            pstmt.close();
72

  
73
            System.out.println("Done.");
74
        } catch (Exception e) {
75
            System.out.println(" column not found.");
76
        }
77

  
78
        // Create nodedatanumerical column in xml_nodes
79
        System.out.println(
80
            "Creating new nodedatanumerical column in xml_nodes...");
81

  
82
        if (database.equals("oracle")) {
83
            pstmt = sqlca.prepareStatement(
84
                "ALTER TABLE xml_nodes ADD nodedatanumerical NUMBER");
85
        }
86
        else {
87
            pstmt = sqlca.prepareStatement(
88
                "ALTER TABLE xml_nodes ADD nodedatanumerical FLOAT8");
89
        }
90
        pstmt.execute();
91
        pstmt.close();
92

  
93
        System.out.println("Done.");
94

  
95
        // Copy numerical values from nodedata to
96
        // nodedatanumerical column in xml_nodes
97
        System.out.println(
98
            "Please be patient as the next upgrade step can be extremely time consuming.");
99
        System.out.println(
100
            "Copy numerical values from nodedata to nodedatanumerical "
101
            + "in xml_nodes...");
102

  
103
        sqlStatement = sqlca.createStatement();
104
        rset = sqlStatement.executeQuery(
105
            "SELECT DISTINCT NODEID, NODEDATA "
106
            + "FROM xml_nodes WHERE "
107
            + "nodedata IS NOT NULL AND "
108
            + "UPPER(nodedata) = LOWER(nodedata)");
109

  
110
        int count = 0;
111
        while (rset.next()) {
112

  
113
            String nodeid = rset.getString(1);
114
            String nodedata = rset.getString(2);
115

  
116
            try {
117
                if (!nodedata.trim().equals("")) {
118
                    double s = Double.parseDouble(nodedata);
119

  
120
                    pstmt = sqlca.prepareStatement(
121
                        "update xml_nodes set nodedatanumerical = " + s +
122
                        " where nodeid=" + nodeid);
123
                    pstmt.execute();
124
                    pstmt.close();
125

  
126
                    count++;
127
                    if (count%5 == 0) {
128
                        System.out.println(count + "...");
129
                    }
130
                }
131
            } catch (NumberFormatException nfe) {
132

  
133
            } catch (Exception e) {
134
                System.out.println("Exception:" + e.getMessage());
135
            }
136
        }
137
        System.out.println("\nDone. " + count + " values copied.");
138

  
139
        rset.close();
140
        sqlStatement.close();
141
    }
142

  
143

  
144
    public static void main(String [] ags){
145

  
146
        try {
147
            Connection sqlca = null;
148

  
149
            // Create a JDBC connection to the database
150
            if (database.equals("oracle")) {
151
            	DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
152
            } 
153
            else if (database.equals("postgresql")) {
154
            	DriverManager.registerDriver(new org.postgresql.Driver());
155
            } 
156
            else if (database.equals("sqlserver")) {
157
            	DriverManager.registerDriver(new com.microsoft.jdbc.sqlserver.SQLServerDriver());
158
            }
159
            
160
            sqlca = DriverManager.getConnection(url, user, password);
161

  
162
            // Upgrade the xml_nodes table only if it oracle
163
	    if (database.equals("oracle")) {
164
            	upgrade_xml_nodes(sqlca);
165
	    }
166
            // Close the connection...
167
            sqlca.close();
168
        } catch (SQLException ex) {
169
            System.out.println("SQLException:" + ex.getMessage());
170
        }
171
    }
172
}
173 0

  
lib/metacat.properties
69 69
database.upgradeVersion.1.9.2=upgrade-db-to-1.9.2
70 70
database.upgradeVersion.1.9.3=upgrade-db-to-1.9.3
71 71
database.upgradeVersion.1.10.0=upgrade-db-to-1.10.0
72
## for running java-based utilities
73
database.upgradeUtility.1.5.0=edu.ucsb.nceas.metacat.admin.upgrade.Upgrade1_5_0
74
database.upgradeUtility.1.10.0=edu.ucsb.nceas.metacat.admin.upgrade.Upgrade1_10_0
72 75
database.initialConnections=5
73 76
database.incrementConnections=5
74 77
database.maximumConnections=200
src/xmltables-oracle.sql
116 116
	docid		VARCHAR2(250),	-- index to the document id
117 117
	date_created	DATE,
118 118
	date_updated	DATE,
119
	nodedatanumerical NUMBER,       -- the data for this node if
120
					-- it is a number
119
	nodedatanumerical NUMBER,       -- the data for this node if it is a number
120
	nodedatadate TIMESTAMP,       -- the data for this node if it is a date
121 121
   CONSTRAINT xml_nodes_pk PRIMARY KEY (nodeid),
122 122
   CONSTRAINT xml_nodes_root_fk
123 123
		FOREIGN KEY (rootnodeid) REFERENCES xml_nodes,
......
162 162
        docid           VARCHAR2(250),  -- index to the document id
163 163
        date_created    DATE,
164 164
        date_updated    DATE,
165
        nodedatanumerical NUMBER,       -- the data for this node if
166
                                        -- it is a number
165
        nodedatanumerical NUMBER,       -- the data for this node if it is a number
166
        nodedatadate TIMESTAMP,       -- the data for this node if it is a date
167 167
   CONSTRAINT xml_nodes_revisions_pk PRIMARY KEY (nodeid),
168 168
   CONSTRAINT xml_nodes_revisions_root_fk
169 169
                FOREIGN KEY (rootnodeid) REFERENCES xml_nodes_revisions,
......
338 338
        path            VARCHAR2(1000), -- precomputed path through tree
339 339
	    nodedata        VARCHAR2(4000), -- the data for this node e.g.,
340 340
        nodedatanumerical NUMBER(20),   -- the data for this node if
341
        parentnodeid    NUMBER(20),     -- index of the parent of this node
341
		nodedatadate TIMESTAMP,       -- the data for this node if it is a date        
342
		parentnodeid    NUMBER(20),     -- index of the parent of this node
342 343
        CONSTRAINT xml_path_index_pk PRIMARY KEY (nodeid),
343 344
        CONSTRAINT xml_path_index_docid_fk FOREIGN KEY (docid) REFERENCES xml_documents
344 345
 );                                                                                        
......
364 365
CREATE INDEX xml_path_index_idx1 ON xml_path_index (path);
365 366
CREATE INDEX xml_path_index_idx2 ON xml_path_index (nodedata);
366 367
CREATE INDEX xml_path_index_idx3 ON xml_path_index (nodedatanumerical);
368
CREATE INDEX xml_path_index_idx4 ON xml_path_index (nodedatadate);
367 369

  
368 370

  
369 371

  
372

  
370 373
CREATE TABLE xml_relation (
371 374
	relationid    NUMBER(20) PRIMARY KEY, -- unique id
372 375
	docid         VARCHAR2(250),          -- the docid of the package file
src/upgrade-db-to-1.10.0-postgres.sql
25 25
);
26 26

  
27 27
/*
28
 * add the nodedatadate column to the tables that need it 
29
 */
30
ALTER TABLE xml_nodes ADD COLUMN nodedatadate TIMESTAMP;
31
ALTER TABLE xml_nodes_revisions ADD COLUMN nodedatadate TIMESTAMP;
32
ALTER TABLE xml_path_index ADD COLUMN nodedatadate TIMESTAMP;
33
CREATE INDEX xml_path_index_idx5 ON xml_path_index (nodedatadate);
34

  
35
/*
28 36
 * Register the DataONE schemas
29 37
 */
30 38
 
src/xmltables-postgres.sql
64 64
	docid VARCHAR(250),	-- index to the document id
65 65
	date_created DATE,
66 66
	date_updated DATE,
67
        nodedatanumerical FLOAT8, -- the data for this node if
68
				  -- if it is a number
67
    nodedatanumerical FLOAT8, -- the data for this node if it is a number
68
    nodedatadate TIMESTAMP, -- the data for this node if it is a date
69 69
   CONSTRAINT xml_nodes_pk PRIMARY KEY (nodeid),
70 70
   CONSTRAINT xml_nodes_root_fk
71 71
		FOREIGN KEY (rootnodeid) REFERENCES xml_nodes,
......
98 98
        docid VARCHAR(250),     -- index to the document id
99 99
        date_created DATE,
100 100
        date_updated DATE,
101
        nodedatanumerical FLOAT8, -- the data for this node if
102
                                  -- if it is a number
101
        nodedatanumerical FLOAT8, -- the data for this node if it is a number
102
        nodedatadate TIMESTAMP, -- the data for this node if it is a date
103 103
   CONSTRAINT xml_nodes_revisions_pk PRIMARY KEY (nodeid),
104 104
   CONSTRAINT xml_nodes_revisions_root_fk
105 105
                FOREIGN KEY (rootnodeid) REFERENCES xml_nodes_revisions,
......
376 376
        path VARCHAR(1000),     -- precomputed path through tree
377 377
        nodedata TEXT, -- the data for this node (e.g.,
378 378
                                -- for TEXT it is the content)
379
        nodedatanumerical FLOAT8, -- the data for this node if
380
                                  -- if it is a number
379
        nodedatanumerical FLOAT8, -- the data for this node if it is a number
380
        nodedatadate TIMESTAMP, -- the data for this node if it is a date
381 381
        parentnodeid INT8,      -- id of the parent of the node represented
382 382
                                -- by this row
383 383
   CONSTRAINT xml_path_index_pk PRIMARY KEY (nodeid),
......
392 392
CREATE INDEX xml_path_index_idx2 ON xml_path_index (nodedata);
393 393
CREATE INDEX xml_path_index_idx3 ON xml_path_index (nodedatanumerical);
394 394
CREATE INDEX xml_path_index_idx4 ON xml_path_index (upper(nodedata));
395
CREATE INDEX xml_path_index_idx5 ON xml_path_index (nodedatadate);
395 396

  
396 397
/*
397 398
 * harvest_site_schedule -- table to store harvest sites and schedule info
src/upgrade-db-to-1.10.0-oracle.sql
24 24
);
25 25

  
26 26
/*
27
 * add the nodedatadate column to xml_nodes 
28
 * TODO: load the data into it (java?)
29
 */
30
ALTER TABLE xml_nodes ADD COLUMN nodedatadate TIMESTAMP;
31
ALTER TABLE xml_nodes_revisions ADD COLUMN nodedatadate TIMESTAMP;
32
ALTER TABLE xml_path_index ADD COLUMN nodedatadate TIMESTAMP;
33
CREATE INDEX xml_path_index_idx4 ON xml_path_index (nodedatadate);
34

  
35

  
36
/*
27 37
 * Register the DataONE schemas
28 38
 */
29 39
INSERT INTO xml_catalog (entry_type, public_id, system_id)
src/edu/ucsb/nceas/metacat/MetaCatServlet.java
33 33
import java.sql.PreparedStatement;
34 34
import java.sql.ResultSet;
35 35
import java.sql.SQLException;
36
import java.sql.Timestamp;
36 37
import java.util.Enumeration;
37 38
import java.util.Hashtable;
38 39
import java.util.Timer;
......
544 545
                                + pathIndex);
545 546
                        if(pathIndex.indexOf("@")<0){
546 547
                            pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
547
                                    + "n.nodedata, n.nodedatanumerical, n.parentnodeid"
548
                                    + "n.nodedata, n.nodedatanumerical, n.nodedatadate, n.parentnodeid"
548 549
                                    + " FROM xml_nodes n, xml_index i WHERE"
549 550
                                    + " i.path = ? and n.parentnodeid=i.nodeid and"
550 551
                                    + " n.nodetype LIKE 'TEXT' order by n.parentnodeid");
551 552
                        } else {
552 553
                            pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
553
                                    + "n.nodedata, n.nodedatanumerical, n.parentnodeid"
554
                                    + "n.nodedata, n.nodedatanumerical, n.nodedatadate, n.parentnodeid"
554 555
                                    + " FROM xml_nodes n, xml_index i WHERE"
555 556
                                    + " i.path = ? and n.nodeid=i.nodeid and"
556 557
                                    + " n.nodetype LIKE 'ATTRIBUTE' order by n.parentnodeid");
......
569 570
                                String docid = rs.getString(1);
570 571
                                String nodedata = rs.getString(2);
571 572
                                float nodedatanumerical = rs.getFloat(3);
572
                                int parentnodeid = rs.getInt(4);
573
                                Timestamp nodedatadate = rs.getTimestamp(4);
574
                                int parentnodeid = rs.getInt(5);
573 575
                                
574 576
                                if (!nodedata.trim().equals("")) {
575 577
                                    pstmt1 = conn.prepareStatement(
576 578
                                            "INSERT INTO xml_path_index"
577 579
                                            + " (docid, path, nodedata, "
578
                                            + "nodedatanumerical, parentnodeid)"
579
                                            + " VALUES (?, ?, ?, ?, ?)");
580
                                            + "nodedatanumerical, nodedatadate, parentnodeid)"
581
                                            + " VALUES (?, ?, ?, ?, ?, ?)");
580 582
                                    
581 583
                                    pstmt1.setString(1, docid);
582 584
                                    pstmt1.setString(2, pathIndex);
583 585
                                    pstmt1.setString(3, nodedata);
584 586
                                    pstmt1.setFloat(4, nodedatanumerical);
585
                                    pstmt1.setInt(5, parentnodeid);
587
                                    pstmt1.setTimestamp(5, nodedatadate);
588
                                    pstmt1.setInt(6, parentnodeid);
586 589
                                    
587 590
                                    pstmt1.execute();
588 591
                                    pstmt1.close();
src/edu/ucsb/nceas/metacat/DocumentImpl.java
44 44
import java.sql.ResultSet;
45 45
import java.sql.SQLException;
46 46
import java.sql.Statement;
47
import java.sql.Timestamp;
47 48
import java.util.Hashtable;
48 49
import java.util.HashMap;
49 50
import java.util.Iterator;
......
1796 1797
        String leafData = leafRecord.getNodeData();
1797 1798
        long leafParentId = leafRecord.getParentNodeId();
1798 1799
        float leafDataNumerical = leafRecord.getNodeDataNumerical();
1800
        Timestamp leafDataDate = leafRecord.getNodeDataDate();
1799 1801
        
1800 1802
        if ( current.getNodeType().equals("ELEMENT") ||
1801 1803
            current.getNodeType().equals("ATTRIBUTE") ) {
......
1817 1819
					logMetacat.debug("DocumentImpl.traverseParents - paths found for indexing: " + currentName);
1818 1820
					pathsFoundForIndexing.put(currentName, new PathIndexEntry(
1819 1821
							leafNodeId, currentName, docid, leafParentId, leafData,
1820
							leafDataNumerical));
1822
							leafDataNumerical, leafDataDate));
1821 1823
				}
1822 1824
            }
1823 1825
            
......
1840 1842
						&& leafData.trim().length() != 0) {
1841 1843
					logMetacat.debug("DocumentImpl.traverseParents - paths found for indexing: " + currentName);
1842 1844
					pathsFoundForIndexing.put(path, new PathIndexEntry(leafNodeId,
1843
							path, docid, leafParentId, leafData, leafDataNumerical));
1845
							path, docid, leafParentId, leafData, leafDataNumerical, leafDataDate));
1844 1846
				}
1845 1847
            }
1846 1848
            // process absolute xpaths
......
1858 1860
					logMetacat.debug("DocumentImpl.traverseParents - paths found for indexing: " + currentName);
1859 1861
					pathsFoundForIndexing.put(fullPath, new PathIndexEntry(
1860 1862
							leafNodeId, fullPath, docid, leafParentId, leafData,
1861
							leafDataNumerical));
1863
							leafDataNumerical, leafDataDate));
1862 1864
				}
1863 1865
            }
1864 1866
        } 
......
1981 1983
        // insertions
1982 1984
        PreparedStatement pstmt = conn.prepareStatement("INSERT INTO "
1983 1985
                + "xml_path_index (docid, path, nodedata, "
1984
                + "nodedatanumerical, parentnodeid)"
1985
                + " VALUES (?, ?, ?, ?, ?)");
1986
                + "nodedatanumerical, nodedatadate, parentnodeid)"
1987
                + " VALUES (?, ?, ?, ?, ?, ?)");
1986 1988
        
1987 1989
        // Step through the hashtable and insert each of the path values
1988 1990
        Iterator<PathIndexEntry> it = pathsFound.values().iterator();
......
2002 2004
             pstmt.setString(2, entry.path);
2003 2005
             pstmt.setString(3, entry.nodeData);
2004 2006
             pstmt.setFloat(4, entry.nodeDataNumerical);
2005
             pstmt.setLong(5, entry.parentId);  
2007
             pstmt.setTimestamp(5, entry.nodeDataDate);
2008
             pstmt.setLong(6, entry.parentId);  
2006 2009
             logMetacat.debug("DocumentImpl.updatePathIndex - executing SQL: " + pstmt.toString());
2007 2010
             pstmt.execute();
2008 2011
        }
......
2241 2244
        String nodeprefix = null;
2242 2245
        String nodedata = null;
2243 2246
        float nodedatanumerical = -1;
2247
        Timestamp nodedatadate = null;
2248

  
2244 2249
//        String quotechar = DatabaseService.getDBAdapter().getStringDelimiter();
2245 2250
        String table = "xml_nodes";
2246 2251
        //System.out.println("in getNodeREcorelist !!!!!!!!!!!for root node id "+rootnodeid);
......
2264 2269
            serialNumber = dbconn.getCheckOutSerialNumber();
2265 2270
            pstmt = dbconn
2266 2271
                    .prepareStatement("SELECT nodeid,parentnodeid,nodeindex, "
2267
                            + "nodetype,nodename,nodeprefix,nodedata, nodedatanumerical "
2272
                            + "nodetype,nodename,nodeprefix,nodedata, nodedatanumerical, nodedatadate "
2268 2273
                            + "FROM " + table + " WHERE rootnodeid = ?");
2269 2274

  
2270 2275
            // Bind the values to the query
......
2293 2298
                	logMetacat.warn("DocumentImpl.getNodeRecordList - StringIndexOutOfBoundsException in normalize() while reading the document");
2294 2299
                }
2295 2300
                nodedatanumerical = rs.getFloat(8);
2301
                nodedatadate = rs.getTimestamp(9);
2302

  
2296 2303
                
2297 2304
                // add the data to the node record list hashtable
2298 2305
                NodeRecord currentRecord = new NodeRecord(nodeid, parentnodeid,
2299
                        nodeindex, nodetype, nodename, nodeprefix, nodedata, nodedatanumerical);
2306
                        nodeindex, nodetype, nodename, nodeprefix, nodedata, nodedatanumerical, nodedatadate);
2300 2307
                nodeRecordList.add(currentRecord);
2301 2308

  
2302 2309
                // Advance to the next node
......
3707 3714
        pstmt = dbconn.prepareStatement("INSERT INTO xml_nodes_revisions "
3708 3715
                + "(nodeid, nodeindex, nodetype, nodename, nodeprefix, "
3709 3716
                + "nodedata, parentnodeid, rootnodeid, docid, date_created,"
3710
                + " date_updated, nodedatanumerical) "
3717
                + " date_updated, nodedatanumerical, nodedatadate) "
3711 3718
                + "SELECT nodeid, nodeindex, nodetype, nodename, nodeprefix, "  
3712 3719
                + "nodedata, parentnodeid, rootnodeid, docid, date_created,"
3713
                + " date_updated, nodedatanumerical "
3720
                + " date_updated, nodedatanumerical, nodedatadate "
3714 3721
                + "FROM xml_nodes WHERE rootnodeid = ?");
3715 3722

  
3716 3723
        // Increase dbconnection usage count
src/edu/ucsb/nceas/metacat/DBSAXNode.java
27 27
package edu.ucsb.nceas.metacat;
28 28

  
29 29
import java.sql.*;
30
import java.text.ParseException;
31
import java.text.SimpleDateFormat;
32
import java.util.Date;
30 33
import java.util.Hashtable;
31 34
import java.util.Enumeration;
32 35
import org.apache.log4j.Logger;
......
173 176
    {
174 177

  
175 178
      PreparedStatement pstmt;
176

  
179
      Timestamp timestampData = null;
180
      
177 181
      if (nodetype == "DOCUMENT") {
178 182
        pstmt = connection.prepareStatement(
179 183
            "INSERT INTO xml_nodes " +
......
186 190
      } else {
187 191
          if(data != null && !data.trim().equals("")
188 192
             && !data.trim().equals("NaN") && !data.trim().equalsIgnoreCase("Infinity")){
189
              try{
190
                  double numberData = Double.parseDouble(data);
193
        	  try{
194
        		  // try some common ISO 8601 formats
195
        		  SimpleDateFormat sdf = null;
196
        		  if (data.length() == 10) {
197
        			  sdf = new SimpleDateFormat("yyyy-MM-dd");
198
        		  } else if (data.length() == 19) {
199
        			  sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
200
        		  } else {
201
        			  // throw this so we continue with parsing as numeric or string.
202
        			  throw new ParseException("String length will not match date/dateTime patterns", -1);
203
        		  }
204
        		  Date dateData = sdf.parse(data);
205
        		  timestampData = new Timestamp(dateData.getTime());
191 206
                  pstmt = connection.prepareStatement(
192 207
                      "INSERT INTO xml_nodes " +
193 208
                      "(nodetype, nodename, nodeprefix, docid, " +
194
                      "rootnodeid, parentnodeid, nodedata, nodeindex, nodedatanumerical) " +
195
                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?, "+ numberData +")");
196
              } catch (NumberFormatException nfe) {
197
                  pstmt = connection.prepareStatement(
198
                      "INSERT INTO xml_nodes " +
199
                      "(nodetype, nodename, nodeprefix, docid, " +
200
                      "rootnodeid, parentnodeid, nodedata, nodeindex) " +
201
                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
209
                      "rootnodeid, parentnodeid, nodedata, nodeindex, nodedatadate) " +
210
                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
211
              } catch (ParseException pe) {
212
	        	  try{
213
	                  double numberData = Double.parseDouble(data);
214
	                  pstmt = connection.prepareStatement(
215
	                      "INSERT INTO xml_nodes " +
216
	                      "(nodetype, nodename, nodeprefix, docid, " +
217
	                      "rootnodeid, parentnodeid, nodedata, nodeindex, nodedatanumerical) " +
218
	                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?, "+ numberData +")");
219
	              } catch (NumberFormatException nfe) {
220
	                  pstmt = connection.prepareStatement(
221
	                      "INSERT INTO xml_nodes " +
222
	                      "(nodetype, nodename, nodeprefix, docid, " +
223
	                      "rootnodeid, parentnodeid, nodedata, nodeindex) " +
224
	                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
225
	              }
202 226
              }
203 227
          } else {
204 228
              pstmt = connection.prepareStatement(
......
235 259
          pstmt.setInt(8, incChildNum());
236 260
        }
237 261
      }
262
      if (timestampData != null) {
263
    	  pstmt.setTimestamp(9, timestampData);
264
      }
238 265
      // Do the insertion
239 266
      logMetacat.debug("DBSAXNode.writeChildNodeToDBDataLimited - SQL insert: " + pstmt.toString());
240 267
      pstmt.execute();
......
329 356
    {
330 357

  
331 358
      PreparedStatement pstmt;
359
      Timestamp timestampData = null;
332 360
      logMetacat.info("DBSAXNode.writeDTDNodeToDB - Insert dtd into db: "+nodename +" "+data);
333 361
      if(data != null && !data.trim().equals("")){
334
            try{
362
    	  try{
363
    		  // try some common ISO 8601 formats
364
    		  SimpleDateFormat sdf = null;
365
    		  if (data.length() == 10) {
366
    			  sdf = new SimpleDateFormat("yyyy-MM-dd");
367
    		  } else if (data.length() == 19) {
368
    			  sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
369
    		  }
370
    		  Date dateData = sdf.parse(data);
371
    		  timestampData = new Timestamp(dateData.getTime());
372
              pstmt = connection.prepareStatement(
373
                  "INSERT INTO xml_nodes " +
374
                  "(nodetype, nodename, docid, " +
375
                  "rootnodeid, parentnodeid, nodedata, nodeindex, nodedatadate) " +
376
                  "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
377
          } catch (ParseException pe) {
378
    	  	try{
335 379
                double numberData = Double.parseDouble(data);
336 380
                pstmt = connection.prepareStatement(
337 381
                    "INSERT INTO xml_nodes " +
......
345 389
                    "rootnodeid, parentnodeid, nodedata, nodeindex) " +
346 390
                    "VALUES (?, ?, ?, ?, ?, ?, ?)");
347 391
            }
392
          }
348 393
        } else {
349 394
            pstmt = connection.prepareStatement(
350 395
                  "INSERT INTO xml_nodes " +
......
364 409
      pstmt.setLong(5, getParentID());
365 410
      pstmt.setString(6, data);
366 411
      pstmt.setInt(7, getNodeIndex());
412
      if (timestampData != null) {
413
    	  pstmt.setTimestamp(8, timestampData);
414
      }
367 415

  
368 416
      // Do the insertion
369 417
      pstmt.execute();
src/edu/ucsb/nceas/metacat/QueryTerm.java
29 29

  
30 30
package edu.ucsb.nceas.metacat;
31 31

  
32
import java.text.ParseException;
33
import java.text.SimpleDateFormat;
34
import java.util.Date;
32 35
import java.util.Vector;
33 36
import org.apache.log4j.Logger;
34 37

  
......
208 211
                                + searchmode);
209 212
                return null;
210 213
            }
214
            
211 215
            try {
212
                // it is number; numeric comparison
213
                // but we need to make sure there is no string in node data
214
                searchexpr = nodedataterm + " " + oper + " "
215
                        + new Double(casevalue) + " ";
216
            } catch (NumberFormatException nfe) {
217
                // these are characters; character comparison
218
                searchexpr = nodedataterm + " " + oper + " '" + casevalue
219
                        + "' ";
220
            }
216
            	// try some common ISO 8601 formats
217
        		SimpleDateFormat sdf = null;
218
        		if (casevalue.length() == 10) {
219
        			sdf = new SimpleDateFormat("yyyy-MM-dd");
220
        		} else if (casevalue.length() == 19) {
221
        			sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
222
        		}
223
        		Date dataDateValue = sdf.parse(casevalue);
224
                nodedataterm = "nodedatadate";
225
        		searchexpr = 
226
        			nodedataterm + " " + oper + " '"
227
        			+ casevalue + "' ";
228
        	} catch (ParseException pe) {
229
	            try {
230
	                // it is number; numeric comparison
231
	                // but we need to make sure there is no string in node data
232
	                searchexpr = nodedataterm + " " + oper + " "
233
	                        + new Double(casevalue) + " ";
234
	            } catch (NumberFormatException nfe) {
235
	                // these are characters; character comparison
236
	                searchexpr = nodedataterm + " " + oper + " '" + casevalue
237
	                        + "' ";
238
	            }
239
        	}
240
            
221 241
        }
222 242

  
223 243

  
src/edu/ucsb/nceas/metacat/PathIndexEntry.java
23 23
 */
24 24
package edu.ucsb.nceas.metacat;
25 25

  
26
import java.sql.Timestamp;
26 27

  
28

  
27 29
/**
28 30
 * PathIndexEntry contains all of the data fields needed to insert an path into
29 31
 * the xml_index table or the xml_path_index table, depending on which 
......
40 42
    protected long parentId;
41 43
    protected String nodeData;
42 44
    protected float nodeDataNumerical;
45
    protected Timestamp nodeDataDate;
43 46

  
47

  
44 48
    /**
45 49
     * Construct a new PathIndexEntry for the xml_index table.
46 50
     *
......
72 76
     * @param nodeDataNumerical the node value as a double precision number
73 77
     */
74 78
    public PathIndexEntry(long nodeId, String path, String docid,
75
            long parentId, String nodeData, float nodeDataNumerical )
79
            long parentId, String nodeData, float nodeDataNumerical, Timestamp nodeDataDate )
76 80
    {
77 81
        this.nodeId = nodeId;
78 82
        this.path = path;
79 83
        this.docid = docid;
80 84
        this.nodeData = nodeData;
81 85
        this.nodeDataNumerical = nodeDataNumerical;
86
        this.nodeDataDate = nodeDataDate;
82 87
        this.parentId = parentId;        
83 88
    }
84 89
}
src/edu/ucsb/nceas/metacat/admin/upgrade/Upgrade1_10_0.java
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$'
10
 *     '$Date$'
11
 * '$Revision$'
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.Statement;
34
import java.sql.DriverManager;
35
import java.sql.Timestamp;
36
import java.text.ParseException;
37
import java.text.SimpleDateFormat;
38
import java.util.Date;
39

  
40
import edu.ucsb.nceas.metacat.admin.AdminException;
41
import edu.ucsb.nceas.metacat.properties.PropertyService;
42
import edu.ucsb.nceas.utilities.SortedProperties;
43

  
44
public class Upgrade1_10_0 implements UpgradeUtilityInterface {
45

  
46
    private String driver = null;
47
    private String url = null;
48
    private String user = null;
49
    private String password = null;
50

  
51
    public boolean upgrade() throws AdminException {
52
    	try {
53
    		// get the properties
54
    		driver = PropertyService.getProperty("database.driver");
55
    	    url = PropertyService.getProperty("database.connectionURI");
56
    	    user = PropertyService.getProperty("database.user");
57
    	    password = PropertyService.getProperty("database.password");
58
    	    
59
	        // Create a JDBC connection to the database    	
60
	    	Connection sqlca = null;
61
	        Driver d = (Driver) Class.forName(driver).newInstance();
62
	        DriverManager.registerDriver(d);
63
	        sqlca = DriverManager.getConnection(url, user, password);
64
	    	
65
	        // three tables need to be updated here
66
	        String[] tablesToUpdate = {"xml_nodes", "xml_nodes_revisions", "xml_path_index"};
67
	        for (String tableName: tablesToUpdate) {
68
		        Statement sqlStatement = null;
69
		        PreparedStatement pstmt = null;
70
		        ResultSet rset = null;
71
		
72
		        sqlStatement = sqlca.createStatement();
73
		        rset = sqlStatement.executeQuery(
74
		            "SELECT DISTINCT NODEID, NODEDATA "
75
		            + "FROM " + tableName + " WHERE "
76
		            + "nodedata IS NOT NULL AND "
77
		            + "UPPER(nodedata) = LOWER(nodedata)");
78
		
79
		        int count = 0;
80
		        while (rset.next()) {
81
		
82
		            String nodeid = rset.getString(1);
83
		            String nodedata = rset.getString(2);
84
		
85
		            try {
86
		                if (!nodedata.trim().equals("")) {
87
		                	boolean skip = false;
88
		                	SimpleDateFormat sdf = null;
89
		            		if (nodedata.length() == 10) {
90
		            			sdf = new SimpleDateFormat("yyyy-MM-dd");
91
		            		} else if (nodedata.length() == 19) {
92
		            			sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
93
		            		} else {
94
		            			skip = true;
95
		            		}
96
		            		if (!skip) {
97
			            		Date dataDateValue = sdf.parse(nodedata);
98
			                    Timestamp dataTimestamp = new Timestamp(dataDateValue.getTime());
99
			
100
			                    pstmt = sqlca.prepareStatement(
101
			                        "update " + tableName +
102
			                        " set nodedatadate = ?" +
103
			                        " where nodeid = " + nodeid);
104
			                    pstmt.setTimestamp(1, dataTimestamp);
105
			                    pstmt.execute();
106
			                    pstmt.close();
107
			
108
			                    count++;
109
			                    if (count%5 == 0) {
110
			                        System.out.println(count + "...");
111
			                    }
112
		            		}
113
		                }
114
		            } catch (ParseException pe) {
115
		            	// do nothing, was not a date
116
		            } 
117
		        }
118
		        System.out.println("Table: " + tableName + " complete. " + count + " values converted.");
119
		
120
		        rset.close();
121
		        sqlStatement.close();
122
	        }
123
	        sqlca.close();
124
    	} catch (Exception e) {
125
    		e.printStackTrace();
126
            throw new AdminException("Error upgrading system to 1.10.0: " + e.getMessage());
127
        }
128
    	return true;
129
    }
130

  
131

  
132
    public static void main(String [] ags){
133

  
134
        try {
135
        	// set up the properties based on the test/deployed configuration of the workspace
136
        	SortedProperties testProperties = 
137
				new SortedProperties("test/test.properties");
138
			testProperties.load();
139
			String metacatContextDir = testProperties.getProperty("metacat.contextDir");
140
			PropertyService.getInstance(metacatContextDir + "/WEB-INF");
141
			// now run it
142
            Upgrade1_10_0 upgrader = new Upgrade1_10_0();
143
            upgrader.upgrade();
144
        } catch (Exception ex) {
145
            System.out.println("Exception:" + ex.getMessage());
146
            ex.printStackTrace();
147
        }
148
    }
149
}
0 150

  
src/edu/ucsb/nceas/metacat/admin/upgrade/Upgrade1_5_0.java
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$'
10
 *     '$Date$'
11
 * '$Revision$'
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.Statement;
34
import java.sql.DriverManager;
35

  
36
import edu.ucsb.nceas.metacat.admin.AdminException;
37
import edu.ucsb.nceas.metacat.properties.PropertyService;
38

  
39
public class Upgrade1_5_0 implements UpgradeUtilityInterface {
40

  
41
    private String driver = null;
42
    private String database = null;
43
    private String url = null;
44
    private String user = null;
45
    private String password = null;
46

  
47
    public boolean upgrade() throws AdminException {
48
    
49
    	try {
50
	    	// get the properties
51
			driver = PropertyService.getProperty("database.driver");
52
			database = PropertyService.getProperty("database.type");
53
		    url = PropertyService.getProperty("database.connectionURI");
54
		    user = PropertyService.getProperty("database.user");
55
		    password = PropertyService.getProperty("database.password");
56
		    
57
		    // only do oracle
58
		    if (!database.equals("oracle")) {
59
		    	return true;
60
		    }
61
		    
62
	        // Create a JDBC connection to the database    	
63
	    	Connection sqlca = null;
64
	        Driver d = (Driver) Class.forName(driver).newInstance();
65
	        DriverManager.registerDriver(d);
66
	        sqlca = DriverManager.getConnection(url, user, password);
67
		    
68
	        Statement sqlStatement = null;
69
	        PreparedStatement pstmt = null;
70
	        ResultSet rset = null;
71
	
72
	        // Delete old nodedatanumerical column from xml_nodes if one exsists
73
	        try {
74
	            System.out.println(
75
	                "Deleting old nodedatanumerical column from xml_nodes...");
76
	
77
	            pstmt = sqlca.prepareStatement(
78
	                "ALTER TABLE xml_nodes DROP COLUMN nodedatanumerical");
79
	            pstmt.execute();
80
	            pstmt.close();
81
	
82
	            System.out.println("Done.");
83
	        } catch (Exception e) {
84
	            System.out.println(" column not found.");
85
	        }
86
	
87
	        // Create nodedatanumerical column in xml_nodes
88
	        System.out.println(
89
	            "Creating new nodedatanumerical column in xml_nodes...");
90
	
91
	        if (database.equals("oracle")) {
92
	            pstmt = sqlca.prepareStatement(
93
	                "ALTER TABLE xml_nodes ADD nodedatanumerical NUMBER");
94
	        }
95
	        else {
96
	            pstmt = sqlca.prepareStatement(
97
	                "ALTER TABLE xml_nodes ADD nodedatanumerical FLOAT8");
98
	        }
99
	        pstmt.execute();
100
	        pstmt.close();
101
	
102
	        System.out.println("Done.");
103
	
104
	        // Copy numerical values from nodedata to
105
	        // nodedatanumerical column in xml_nodes
106
	        System.out.println(
107
	            "Please be patient as the next upgrade step can be extremely time consuming.");
108
	        System.out.println(
109
	            "Copy numerical values from nodedata to nodedatanumerical "
110
	            + "in xml_nodes...");
111
	
112
	        sqlStatement = sqlca.createStatement();
113
	        rset = sqlStatement.executeQuery(
114
	            "SELECT DISTINCT NODEID, NODEDATA "
115
	            + "FROM xml_nodes WHERE "
116
	            + "nodedata IS NOT NULL AND "
117
	            + "UPPER(nodedata) = LOWER(nodedata)");
118
	
119
	        int count = 0;
120
	        while (rset.next()) {
121
	
122
	            String nodeid = rset.getString(1);
123
	            String nodedata = rset.getString(2);
124
	
125
	            try {
126
	                if (!nodedata.trim().equals("")) {
127
	                    double s = Double.parseDouble(nodedata);
128
	
129
	                    pstmt = sqlca.prepareStatement(
130
	                        "update xml_nodes set nodedatanumerical = " + s +
131
	                        " where nodeid=" + nodeid);
132
	                    pstmt.execute();
133
	                    pstmt.close();
134
	
135
	                    count++;
136
	                    if (count%5 == 0) {
137
	                        System.out.println(count + "...");
138
	                    }
139
	                }
140
	            } catch (NumberFormatException nfe) {
141
	
142
	            } catch (Exception e) {
143
	                System.out.println("Exception:" + e.getMessage());
144
	            }
145
	        }
146
	        System.out.println("\nDone. " + count + " values copied.");
147
	
148
	        rset.close();
149
	        sqlStatement.close();
150
	        sqlca.close();
151
    	} catch (Exception e) {
152
            throw new AdminException("Error upgrading system to 1.5: " + e.getMessage());
153
        }
154
    	return true;
155

  
156
    }
157

  
158

  
159
    public static void main(String [] ags){
160

  
161
        try {
162
            Upgrade1_5_0 upgrader = new Upgrade1_5_0();
163
            upgrader.upgrade();
164
        
165
        } catch (Exception ex) {
166
            System.out.println("Exception:" + ex.getMessage());
167
        }
168
    }
169
}
0 170

  
src/edu/ucsb/nceas/metacat/admin/upgrade/UpgradeUtilityInterface.java
1
package edu.ucsb.nceas.metacat.admin.upgrade;
2

  
3
import edu.ucsb.nceas.metacat.admin.AdminException;
4

  
5
public interface UpgradeUtilityInterface {
6

  
7
	public boolean upgrade() throws AdminException;
8
}
0 9

  
src/edu/ucsb/nceas/metacat/admin/DBAdmin.java
50 50
import javax.servlet.http.HttpSession;
51 51

  
52 52
import edu.ucsb.nceas.metacat.MetacatVersion;
53
import edu.ucsb.nceas.metacat.admin.upgrade.UpgradeUtilityInterface;
53 54
import edu.ucsb.nceas.metacat.database.DBConnection;
54 55
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
55 56
import edu.ucsb.nceas.metacat.database.DBVersion;
......
736 737
		return updateScriptList;
737 738
	}
738 739

  
740
	public Vector<String> getUpdateClasses() throws AdminException {
741
		Vector<String> updateClassList = new Vector<String>();
742
		MetacatVersion metaCatVersion = null; 
743
		
744
		// get the location of sql scripts
745
		try {
746
			metaCatVersion = SystemUtil.getMetacatVersion();
747
		} catch (PropertyNotFoundException pnfe) {
748
			throw new AdminException("DBAdmin.getUpdateScripts - Could not get property while trying " 
749
					+ "to retrieve update utilities: " + pnfe.getMessage());
750
		}
751
		
752
		// if either of these is null, we don't want to do anything.  Just 
753
		// return an empty list.
754
		if (metaCatVersion == null || databaseVersion == null) {
755
			return updateClassList;
756
		}
757

  
758
		// go through all the versions that the the software went through and 
759
		// figure out which ones need to be applied to the database	
760
		for (DBVersion nextVersion : versionSet) {
761

  
762
			// add every update script that is > than the db version
763
			// but <= to the metacat version to the update list.
764
			if (nextVersion.compareTo(databaseVersion) > 0
765
					&& nextVersion.compareTo(metaCatVersion) <= 0) {
766
				String key = "database.upgradeUtility." + nextVersion.getVersionString();
767
				String className = null;
768
				try {
769
					className = PropertyService.getProperty(key);
770
				} catch (PropertyNotFoundException pnfe) {
771
					// there probably isn't a utility needed for this version
772
					logMetacat.warn("No utility defined for version: " + key);
773
					continue;
774
				}
775
				updateClassList.add(className);
776
			}
777
		}
778

  
779
		// this should now hold all the script names that need to be run
780
		// to bring the database up to date with this version of metacat
781
		return updateClassList;
782
	}
783
	
739 784
	/**
740 785
	 * Iterates through the list of scripts that need to be run to upgrade
741 786
	 * the database and calls runSQLFile on each.
......
749 794
			for (String updateScript : updateScriptList) {
750 795
				runSQLFile(updateScript);
751 796
			}
797
			
798
			// get the classes we need to execute in order to bring DB to current version
799
			Vector<String> updateClassList = getUpdateClasses();
800
			for (String className : updateClassList) {
801
				UpgradeUtilityInterface utility = null;
802
				try {
803
					utility = (UpgradeUtilityInterface) Class.forName(className).newInstance();
804
					utility.upgrade();
805
				} catch (Exception e) {
806
					throw new AdminException("DBAdmin.upgradeDatabase - error getting utility class: " 
807
							+ className + ". Error message: "
808
							+ e.getMessage());
809
				}
810
			}
752 811

  
753 812
			// update the db version to be the metacat version
754 813
			databaseVersion = new DBVersion(SystemUtil.getMetacatVersion().getVersionString());
src/edu/ucsb/nceas/metacat/NodeRecord.java
26 26

  
27 27
package edu.ucsb.nceas.metacat;
28 28

  
29
import java.sql.Timestamp;
30

  
29 31
import org.apache.log4j.Logger;
30 32

  
31 33
/**
......
40 42
  private String _nodetype = null;
41 43
  private String _nodedata = null;
42 44
  private float _nodedatanumerical = -1;
45
  private Timestamp _nodedatadate = null;
46

  
43 47
  private Logger logMetacat = Logger.getLogger(NodeRecord.class);
44 48

  
45 49
  /**
......
58 62
  }
59 63
  
60 64
  public NodeRecord(long nodeid, long parentnodeid, long nodeindex, String nodetype,
61
			String nodename, String nodeprefix, String nodedata, float nodedatanumerical) {
65
			String nodename, String nodeprefix, String nodedata, float nodedatanumerical, Timestamp nodedatadate) {
62 66
		setNodeId(nodeid);
63 67
		setParentNodeId(parentnodeid);
64 68
		setNodeIndex(nodeindex);
......
67 71
		setNodeType(nodetype);
68 72
		setNodeData(nodedata);
69 73
		setNodeDataNumerical(nodedatanumerical);
74
		setNodeDataDate(nodedatadate);
70 75
	}
71 76
  
72 77
  /** Get functions */
......
110 115
    return _nodedatanumerical;
111 116
  }
112 117
  
118
  public Timestamp getNodeDataDate()
119
  {
120
    return _nodedatadate;
121
  }
122
  
113 123
  /** Setter methods **/
114 124
  
115 125
  /**
......
200 210
    _nodedatanumerical = datanumerical;
201 211
  }
202 212
  
213
  public void setNodeDataDate(Timestamp datadate){
214
	    _nodedatadate = datadate;
215
	  }
216
  
203 217
  /** Method compare two records */
204 218
  public boolean contentEquals(NodeRecord record)
205 219
  {
src/xmltables-sqlserver.sql
124 124
  [docid]		[varchar] (250) NULL ,
125 125
  [date_created]	[datetime] NULL ,
126 126
  [date_updated]	[datetime] NULL, 
127
  [nodedatanumerical]   [float] NULL
127
  [nodedatanumerical]   [float] NULL,
128
  [nodedatadate]   [datetime] NULL
128 129
) ON [PRIMARY]
129 130
GO
130 131

  

Also available in: Unified diff