001: /******************************************************************
002: * File: Driver_MsSQL.java
003: * Created by: Dave Reynolds
004: * Created on: 02-Nov-2005
005: *
006: * (c) Copyright 2005, Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: Driver_MsSQL.java,v 1.6 2008/01/02 12:08:23 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.db.impl;
010:
011: import java.sql.PreparedStatement;
012: import java.sql.ResultSet;
013: import java.sql.SQLException;
014: import java.util.Properties;
015:
016: import com.hp.hpl.jena.db.IDBConnection;
017: import com.hp.hpl.jena.db.RDFRDBException;
018:
019: /**
020: * This is a driver file for MS SQL Server 2000, MSDE 2000 and
021: * SQL Server 2005 (inc MS SQL Server Express).
022: * <p>
023: * There is very little difference from the postgres driver except for the
024: * use of script inheritance to override some of the postgresql SQL commands and
025: * a small difference in the use of ID allocation.
026: * <p>
027: * The id allocation approach was adopted from an earlier driver by Erik Barke (eba@ur.se)
028: * <p>
029: * N.B. If the postgresql driver file is changed this should be reviewed
030: * for impact.
031: *
032: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
033: * @version $Revision: 1.6 $
034: */
035:
036: public class Driver_MsSQL extends Driver_PostgreSQL {
037:
038: /** Default SQL file from which this driver inherits base operations */
039: protected static final String DEFAULT_SQL = "etc/postgresql.sql";
040:
041: /**
042: * Constructor. Sets up all the interesting parameters.
043: */
044: public Driver_MsSQL() {
045: super ();
046:
047: String myPackageName = this .getClass().getPackage().getName();
048:
049: DATABASE_TYPE = "MsSQL";
050: DRIVER_NAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
051:
052: ID_SQL_TYPE = "INTEGER";
053: URI_COMPRESS = false;
054: INDEX_KEY_LENGTH_MAX = INDEX_KEY_LENGTH = 225;
055: LONG_OBJECT_LENGTH_MAX = LONG_OBJECT_LENGTH = 225;
056: TABLE_NAME_LENGTH_MAX = 128;
057: IS_XACT_DB = true;
058: PRE_ALLOCATE_ID = false;
059: SKIP_DUPLICATE_CHECK = false;
060: SQL_FILE = "etc/mssql.sql";
061: QUOTE_CHAR = '\'';
062: DB_NAMES_TO_UPPER = false;
063: setTableNames(TABLE_NAME_PREFIX);
064:
065: m_psetClassName = myPackageName + ".PSet_TripleStore_RDB";
066: m_psetReifierClassName = myPackageName + ".PSet_ReifStore_RDB";
067:
068: m_lsetClassName = myPackageName
069: + ".SpecializedGraph_TripleStore_RDB";
070: m_lsetReifierClassName = myPackageName
071: + ".SpecializedGraphReifier_RDB";
072: }
073:
074: /**
075: * Set the database connection
076: */
077: public void setConnection(IDBConnection dbcon) {
078: m_dbcon = dbcon;
079:
080: try {
081: Properties defaultSQL = SQLCache.loadSQLFile(DEFAULT_SQL,
082: null, ID_SQL_TYPE);
083: m_sql = new SQLCache(SQL_FILE, defaultSQL, dbcon,
084: ID_SQL_TYPE);
085: } catch (Exception e) {
086: e.printStackTrace(System.err);
087: logger.error("Unable to set connection for Driver:", e);
088: }
089: }
090:
091: /**
092: * Insert a long object into the database.
093: * This assumes the object is not already in the database.
094: * Almost a clone of the standard code in Driver_RDB but
095: * returns the ID from the insert instead of from a separate call.
096: *
097: * @return the db index of the added literal
098: */
099: public DBIDInt addRDBLongObject(RDBLongObject lobj, String table)
100: throws RDFRDBException {
101: DBIDInt result = null;
102: try {
103: int argi = 1;
104: String opname = "insertLongObject";
105: PreparedStatement ps = m_sql.getPreparedSQLStatement(
106: opname, table);
107:
108: ps.setString(argi++, lobj.head);
109: if (lobj.tail.length() > 0) {
110: ps.setLong(argi++, lobj.hash);
111: ps.setString(argi++, lobj.tail);
112: } else {
113: ps.setNull(argi++, java.sql.Types.BIGINT);
114: ps.setNull(argi++, java.sql.Types.LONGVARCHAR);
115: }
116:
117: ResultSet rs = ps.executeQuery();
118: if (rs.next()) {
119: result = wrapDBID(rs.getObject(1));
120: } else {
121: throw new RDFRDBException("No insert ID");
122: }
123:
124: return result;
125:
126: } catch (Exception e1) {
127: throw new RDFRDBException("Failed to add long object ", e1);
128: }
129: }
130:
131: /**
132: * Allocate an identifier for a new graph.
133: *
134: */
135: public int graphIdAlloc(String graphName) {
136: DBIDInt result = null;
137: try {
138: PreparedStatement ps = m_sql.getPreparedSQLStatement(
139: "insertGraph", GRAPH_TABLE);
140: ps.setString(1, graphName);
141: ResultSet rs = ps.executeQuery();
142: if (rs.next()) {
143: result = wrapDBID(rs.getObject(1));
144: } else {
145: throw new RDFRDBException("No insert ID");
146: }
147: } catch (SQLException e) {
148: throw new RDFRDBException(
149: "Failed to get last inserted ID: " + e);
150: }
151: return result.getIntID();
152: }
153:
154: /**
155: * Return the parameters for table creation.
156: * 1) column type for subj, prop, obj.
157: * 2) column type for head.
158: * 3) table and index name prefix.
159: * @param param array to hold table creation parameters.
160: */
161: protected void getTblParams(String[] param) {
162: String spoColType;
163: String headColType;
164:
165: if (LONG_OBJECT_LENGTH > 4000)
166: throw new RDFRDBException("Long object length specified ("
167: + LONG_OBJECT_LENGTH
168: + ") exceeds maximum sane length of 4000.");
169: if (INDEX_KEY_LENGTH > 4000)
170: throw new RDFRDBException("Index key length specified ("
171: + INDEX_KEY_LENGTH
172: + ") exceeds maximum sane length of 4000.");
173:
174: spoColType = "NVARCHAR(" + LONG_OBJECT_LENGTH + ")";
175: STRINGS_TRIMMED = false;
176: param[0] = spoColType;
177: headColType = "NVARCHAR(" + INDEX_KEY_LENGTH + ")";
178: STRINGS_TRIMMED = false;
179: param[1] = headColType;
180: param[2] = TABLE_NAME_PREFIX;
181: }
182:
183: // Suppressed. This was an attempt to force use of row level locking to
184: // get round concurrency problems. Code level in comment form for future reference.
185: // public String createTable( int graphId, boolean isReif) {
186: // String tableName = super.createTable(graphId, isReif);
187: // try {
188: // xactOp(xactCommit);
189: // m_sql.runSQLGroup("setLockLevel", tableName);
190: // xactOp(xactBegin);
191: // } catch (SQLException e) {
192: // logger.error("Problem creating table", e);
193: // throw new RDFRDBException("Failed to set lock level in statement table", e);
194: // }
195: // return tableName;
196: // }
197:
198: // TODO: Review string match op codes
199: // TODO: Check case sensitivity of URI retrieval
200: // Case sensitive search is a problem (SQL Server 2000 defaults to case insensitive and
201: // you only change it by defining collation order for the column/table, earlier
202: // SQL Servers required a database reinstallation to change the collation order).
203:
204: }
205:
206: /*
207: (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
208: All rights reserved.
209:
210: Redistribution and use in source and binary forms, with or without
211: modification, are permitted provided that the following conditions
212: are met:
213:
214: 1. Redistributions of source code must retain the above copyright
215: notice, this list of conditions and the following disclaimer.
216:
217: 2. Redistributions in binary form must reproduce the above copyright
218: notice, this list of conditions and the following disclaimer in the
219: documentation and/or other materials provided with the distribution.
220:
221: 3. The name of the author may not be used to endorse or promote products
222: derived from this software without specific prior written permission.
223:
224: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
225: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
226: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
227: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
229: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
230: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
233: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
234: */
|