[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[stellation-res] Oracle backend!
|
Hello,
Based on Mark's explanation that is also copied to the Eclipse Wiki, I
started writing an Oracle backend. I'm now at the point where I have
been able to run the command
svc --location=oracle:svc configure database
successfully. There are some remarks however:
1) For the long string, I have used Oracle's VARCHAR(2000). If my
colleague has informed me well, this seems to be the largest size
possible. In the DB2 version, it was put on 16000, so I will have to
look into this further.
2) Some of the column names that are specified in the
DBAccessPoint/ArtifactAgents are Oracle reserved words:
a) [DBAccessPoint] Comments table: the column 'comment' should be
renamed for the statement to work in Oracle.
b) [DataArtifactAgent] the 'size' column should be renamed for the
statement to work in Oracle.
3) I haven't run anything but configure database. I consider this a
first milestone for the Oracle backend. In OracleAccessPoint, one will
notice that it uses the Thin Oracle JDBC driver hardcoded to my own
machine (p_ringo). I want Stellation to run first before I will delve
deeper into DB connection configuration.
4) Concerning column and table names: should we prefix the names to
prevent conflicts with *any* RDBM system?
Oracle backend code attached as patch.
Please check in this code so I can continue working from CVS HEAD.
Ringo
__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com
Index: org/eclipse/stellation/repos/OracleAccessPoint.java
===================================================================
RCS file: org/eclipse/stellation/repos/OracleAccessPoint.java
diff -N org/eclipse/stellation/repos/OracleAccessPoint.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ org/eclipse/stellation/repos/OracleAccessPoint.java 24 Jul 2002 09:28:38 -0000
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+// $Id$
+package org.eclipse.stellation.repos;
+
+import org.eclipse.stellation.util.StringList;
+import org.eclipse.stellation.repos.artifact.ArtifactAgent;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Supports access to an Oracle8i Database.
+ */
+public class OracleAccessPoint extends DBAccessPoint implements AccessPoint{
+
+ static {
+ try {
+ Class.forName("oracle.jdbc.OracleDriver").newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("Error initializing database driver");
+ System.exit(0);
+ }
+ }
+
+ /**
+ * Constructs new Oracle access point given an access string and a database name.
+ *
+ * @param dbspec access string. This consists of database name
+ * alone, or else database name followed by colon followed by
+ * username followed by colon followed by password. The user name
+ * and password must be those of a oracle instance account.
+ * @throws DatabaseException if unable to access database
+ * @throws IOException if error accessing database
+ */
+ public OracleAccessPoint(StringList args)
+ throws DatabaseException, IOException {
+
+ super("oracle", // database manager name
+ args.get(0),
+ "BLOB", // type for data artifacts
+ "NUMBER(20,0)", // name of standard integer type
+ "VARCHAR2(200)", // "short" string type
+ "VARCHAR2(2000)" , // "long" string type
+ "NUMBER(20,0)"); // integer type to use for times
+ logger.debug("oracle access " + args.get(0));
+ args.remove(0);
+ if (args.size()>1) {
+ _username = args.remove(0);
+ _password = args.remove(0);
+ }
+ //hack
+ _username = "svcu";
+ _password = "svcp";
+
+ try {
+ logger.debug("trying oracleconnect ");
+ logger.debug("trying name " + getName());
+ if (_username == null) { /* if connecting via user id */
+ _conn = DriverManager
+ .getConnection("jdbc:oracle:thin:@p_ringo:1521:" + getName());
+ }
+ else {
+ logger.debug("trying oracleusername " +
+ _username + ", password " + _password);
+ _conn = DriverManager
+ .getConnection("jdbc:oracle:thin:@p_ringo:1521:" + getName(),
+ _username,
+ _password);
+ }
+ logger.debug("connect back...");
+ } catch (SQLException sqe) {
+ sqe.printStackTrace();
+ throw new DatabaseException(this, "Error connecting to database server", sqe);
+ }
+ }
+ /**
+ * Processes access error by throwing an exception.
+ *
+ * @param message error message string
+ * @throws IOException to indicate an access error occurred
+ */
+ void accessError(String message) throws IOException {
+ throw new IOException(message);
+ }
+
+ /**
+ * Returns string to be used to create a table. This string can be
+ * used to provide database manager options, but no such options
+ * are currently used for Oracle.
+ *
+ * @param name table name
+ * @return string with first part of SQL CREATE TABLE statement
+ * for the specified name.
+ */
+ public String createTable(String name) {
+ return "CREATE TABLE " + name + " (";
+ }
+
+ /**
+ * Returns string to be used to close a statement that creates a table.
+ * The Oracle version gives a tablespace name.
+ *
+ * @param name table name
+ * @return string with final part of SQL CREATE TABLE statement
+ * for the specified name.
+ */
+ public String endTable(String name) {
+ return "";
+ }
+
+ /**
+ * Creates the repository associated with this server.
+ *
+ * @param specfile a JDOM document specifying the artifact types
+ * in the repository. The file contains an XML artifacts element,
+ * containing artifact elements, which have an "artifactclass"
+ * attribute, and a "agentclass" attribute, which specify the
+ * names of the artifact and agent classnames for the artifact
+ * type.
+ * @throws DatabaseException if theres an error creating the *
+ * repository.
+ */
+ public void createRepository(String reposTag, Document configDoc) throws RepositoryException {
+ String datasrc = "jdbc:" + _dbkind + ":" + _dbname;
+ Element rootEl = configDoc.getDocumentElement();
+
+ NodeList nodeList = rootEl.getElementsByTagName("Administrator");
+
+ Element userEl = (Element) nodeList.item(0);
+ String username = userEl.getAttribute("username");
+ String password = userEl.getAttribute("password");
+ try {
+ Statement stmt = _conn.createStatement();
+
+ stmt.execute("CREATE TABLE ReposTag(" + string("tag", "") + ")");
+ stmt.execute("INSERT INTO ReposTag(tag) VALUES ('" + reposTag + "')");
+
+ stmt.execute(createTable("Users") +
+ integer("id", " PRIMARY KEY,") +
+ string("name", ",") +
+ string("password", ",") +
+ string("privs", ")") +
+ endTable("Users")
+ );
+
+ stmt.execute(createTable("Agents") +
+ string("type", " PRIMARY KEY,") +
+ string("artifactclass", ",") +
+ string("agentclass", ")") +
+ endTable("Agents"));
+
+ stmt.execute(createTable("Artifacts") +
+ integer("id", " PRIMARY KEY,") +
+ integer("creator", " REFERENCES Users,") +
+ string("type", " REFERENCES Agents,") +
+ time("time", ")") +
+ endTable("Artifacts"));
+
+ stmt.execute(createTable("Comments") +
+ integer("id", " PRIMARY KEY,") +
+ longString("svcComment", ")") +
+ endTable("Comments"));
+ stmt.execute("INSERT INTO Comments(id, svcComment) VALUES (0,' ')");
+
+ stmt.execute(createTable("Versions") +
+ integer("aid", " REFERENCES Artifacts,") +
+ integer("vid", ",") +
+ integer("creator", " REFERENCES Users,") +
+ time("time", ",") +
+ "PRIMARY KEY(aid,vid))" +
+ endTable("Versions"));
+
+ stmt.execute(createTable("Authenticators") +
+ string("name", " PRIMARY KEY,") +
+ string("class", ")") +
+ endTable("Authenticators"));
+
+ stmt.execute(createTable("Projects") +
+ string("name", " PRIMARY KEY,") +
+ integer("creator", " REFERENCES Users,") +
+ integer("rootArtifact", " REFERENCES Artifacts,") +
+ time("time", ",") +
+ integer("cid", " REFERENCES Comments)") +
+ endTable("Projects"));
+
+ stmt.execute(createTable("Branches") +
+ integer("id", " PRIMARY KEY,") +
+ string("project", " REFERENCES Projects,") +
+ string("name", ",") +
+ integer("head", ",") +
+ integer("creator", " REFERENCES Users,") +
+ integer("cid", " REFERENCES Comments)") +
+ endTable("Branches"));
+
+
+ stmt.execute(createTable("BranchVersions") +
+ integer("branch", " REFERENCES Branches,") +
+ integer("vid", ",") +
+ integer("creator", " REFERENCES Users,") +
+ time("time", ",") +
+ integer("cid", " REFERENCES Comments,") +
+ "PRIMARY KEY(branch, vid))" +
+ endTable("BranchVersions"));
+
+ stmt.execute(createTable("BranchContents") +
+ integer("branch", ",") +
+ integer("branchvid", ",") +
+ integer("aid", ",") +
+ integer("vid", ",") +
+ integer("executable", ",") +
+ "CONSTRAINT fkbc1 FOREIGN KEY " +
+ "(branch,branchvid) REFERENCES BranchVersions (branch,vid)," +
+ "CONSTRAINT fkbc2 FOREIGN KEY " +
+ "(aid,vid) REFERENCES Versions (aid,vid))" +
+ endTable("BranchContents"));
+
+
+ stmt.execute(createTable("BranchHistory") +
+ integer("branch", ",") +
+ integer("vid", ",") +
+ integer("parent", ",") +
+ integer("parentvid", ",") +
+ "CONSTRAINT fk1 FOREIGN KEY (branch,vid) REFERENCES BranchVersions(branch,vid)," +
+ "CONSTRAINT fk2 FOREIGN KEY (parent,parentvid) REFERENCES BranchVersions(branch,vid), " +
+ "PRIMARY KEY(branch, vid,parent, parentvid))" +
+ endTable("BranchHistory"));
+
+ stmt.execute(createTable("Indices") +
+ string("name", " PRIMARY KEY,") +
+ integer("value", ")") +
+ endTable("Indices"));
+
+ stmt.execute(createTable("Properties") +
+ integer("aid", ",") +
+ integer("vid", ",") +
+ integer("inheritable", ",") +
+ string("name", ",") +
+ string("value", ",") +
+ "CONSTRAINT fk3 FOREIGN KEY (aid,vid) REFERENCES Versions(aid,vid)," +
+ "PRIMARY KEY(aid,vid,name))" +
+ endTable("Properties"));
+
+ // Then, insert some initial values
+
+ stmt.execute("INSERT INTO Indices(name, value) VALUES ( 'UserIDs', 1 )");
+
+ stmt.execute("INSERT INTO Indices(name, value) VALUES ( 'ArtifactIDs', 0)");
+
+ stmt.execute("INSERT INTO Indices(name, value) VALUES ( 'CommentIDs', 0)");
+
+ stmt.execute("INSERT INTO Indices(name, value) VALUES ( 'BranchIDs', 0)");
+
+ String ustmt ="INSERT INTO Users(id, name, password, privs) " +
+ "VALUES (" +
+ "0," +
+ quote(username, ",") +
+ quote(password, ",") +
+ quote("ALL",")") ;
+ logger.debug("user stmt " + ustmt);
+ stmt.execute("INSERT INTO Users(id, name, password, privs) " +
+ "VALUES (" +
+ "0," +
+ quote(username, ",") +
+ quote(password, ",") +
+ quote("ALL",")") );
+ logger.debug("Inserted original entries into Indices and Users");
+ // Insert the authenticator values:
+ nodeList = rootEl.getElementsByTagName("ClientLogChallenge");
+ for (int authi = 0; authi < nodeList.getLength(); authi++) {
+ Element authEl = (Element) nodeList.item(authi);
+ String name = authEl.getAttribute("name");
+ String clazz = authEl.getAttribute("class");
+
+ stmt.execute("INSERT INTO Authenticators(name, class) VALUES (" +
+ quote(name,",") +
+ quote(clazz, ")"));
+ }
+ nodeList = rootEl.getElementsByTagName("ArtifactAgent");
+ for (int authi = 0; authi < nodeList.getLength(); authi++) {
+ Element artEl = (Element) nodeList.item(authi);
+ String type = artEl.getAttribute("type");
+ String aclass = artEl.getAttribute("artifactclass");
+ String agclass = artEl.getAttribute("agentclass");
+
+ stmt.execute("INSERT INTO Agents(type, artifactclass, agentclass) VALUES (" +
+ quote(type, ",") +
+ quote(aclass, ",") +
+ quote(agclass, ")"));
+ }
+
+ LocalHandle repos = new LocalHandle(this, getName(), username);
+ Iterator agents = repos.getArtifactAgents();
+ while (agents.hasNext()) {
+ ArtifactAgent agent = (ArtifactAgent) agents.next();
+ logger.debug("initializing storage for agent " + agent.getArtifactType());
+ agent.initializeStorage();
+ }
+ } catch (SQLException sqe) {
+ sqe.printStackTrace();
+ throw new DatabaseException(
+ this,
+ "Database error creating repository " + getName(),
+ sqe);
+ }
+
+ }
+
+ private static String getDatabaseName(String access) {
+ int colon = access.indexOf(':');
+ if (colon>0) {
+ return access.substring(0,colon);
+ }
+ return access;
+ }
+
+ private String _username;
+
+ private String _password;
+
+
+ static final Logger logger = Logger.getLogger(OracleAccessPoint.class);
+}
Index: org/eclipse/stellation/repos/artifact/DataArtifactAgent.java
===================================================================
RCS file: /home/technology/org.eclipse.stellation/plugins/org.eclipse.stellation.core/src/org/eclipse/stellation/repos/artifact/DataArtifactAgent.java,v
retrieving revision 1.3
diff -u -r1.3 DataArtifactAgent.java
--- org/eclipse/stellation/repos/artifact/DataArtifactAgent.java 17 Jul 2002 13:46:54 -0000 1.3
+++ org/eclipse/stellation/repos/artifact/DataArtifactAgent.java 24 Jul 2002 09:28:40 -0000
@@ -70,7 +70,7 @@
getServer().integer("aid", ",") +
getServer().integer("vid", ",") +
getServer().blob("contents", ",") +
- getServer().integer("size", ",") +
+ getServer().integer("svcSize", ",") +
"CONSTRAINT fkdata FOREIGN KEY (aid,vid) REFERENCES Versions(aid,vid)," +
"PRIMARY KEY(aid, vid))" +
getServer().endTable("Datas"));
Index: org/eclipse/stellation/repos/messaging/server/RepositoryServer.java
===================================================================
RCS file: /home/technology/org.eclipse.stellation/plugins/org.eclipse.stellation.core/src/org/eclipse/stellation/repos/messaging/server/RepositoryServer.java,v
retrieving revision 1.2
diff -u -r1.2 RepositoryServer.java
--- org/eclipse/stellation/repos/messaging/server/RepositoryServer.java 19 Jul 2002 17:40:17 -0000 1.2
+++ org/eclipse/stellation/repos/messaging/server/RepositoryServer.java 24 Jul 2002 09:28:39 -0000
@@ -24,6 +24,7 @@
import org.eclipse.stellation.repos.AccessPoint;
import org.eclipse.stellation.repos.DB2AccessPoint;
import org.eclipse.stellation.repos.DBAccessPoint;
+import org.eclipse.stellation.repos.OracleAccessPoint;
import org.eclipse.stellation.repos.PostgresAccessPoint;
import org.eclipse.stellation.repos.RepositoryException;
import org.eclipse.stellation.util.Option;
@@ -49,6 +50,8 @@
_ap = new DB2AccessPoint(apSpecList);
else if (dbtype.equals("postgres"))
_ap = new PostgresAccessPoint(apSpecList.remove(0));
+ else if (dbtype.equals("oracle"))
+ _ap = new OracleAccessPoint(apSpecList);
else {
System.err.println("Invalid access point specification");
throw new RepositoryException((AccessPoint)null, "Could not create access point: invalid location spec");
Index: org/eclipse/stellation/workspace/Configure.java
===================================================================
RCS file: /home/technology/org.eclipse.stellation/plugins/org.eclipse.stellation.core/src/org/eclipse/stellation/workspace/Configure.java,v
retrieving revision 1.2
diff -u -r1.2 Configure.java
--- org/eclipse/stellation/workspace/Configure.java 14 Jul 2002 21:43:41 -0000 1.2
+++ org/eclipse/stellation/workspace/Configure.java 24 Jul 2002 09:28:41 -0000
@@ -18,6 +18,7 @@
import org.eclipse.stellation.repos.AccessPoint;
import org.eclipse.stellation.repos.DB2AccessPoint;
import org.eclipse.stellation.repos.DBAccessPoint;
+import org.eclipse.stellation.repos.OracleAccessPoint;
import org.eclipse.stellation.repos.PostgresAccessPoint;
import org.eclipse.stellation.repos.RepositoryException;
import org.eclipse.stellation.util.DOM;
@@ -144,6 +145,9 @@
Location location = new Location(locationOption);
if (location.isDB2Protocol()) {
s = new DB2AccessPoint(location.getList());
+ }
+ else if (location.isOracleProtocol()) {
+ s = new OracleAccessPoint(location.getList());
}
else if (location.isPostgresqlProtocol()) {
s = new PostgresAccessPoint(location.getDatabase());
Index: org/eclipse/stellation/workspace/Connection.java
===================================================================
RCS file: /home/technology/org.eclipse.stellation/plugins/org.eclipse.stellation.core/src/org/eclipse/stellation/workspace/Connection.java,v
retrieving revision 1.2
diff -u -r1.2 Connection.java
--- org/eclipse/stellation/workspace/Connection.java 9 Jul 2002 18:44:36 -0000 1.2
+++ org/eclipse/stellation/workspace/Connection.java 24 Jul 2002 09:28:42 -0000
@@ -20,6 +20,7 @@
import org.eclipse.stellation.repos.DB2AccessPoint;
import org.eclipse.stellation.repos.DatabaseException;
import org.eclipse.stellation.repos.Handle;
+import org.eclipse.stellation.repos.OracleAccessPoint;
import org.eclipse.stellation.repos.PasswordAuthenticator;
import org.eclipse.stellation.repos.PostgresAccessPoint;
import org.eclipse.stellation.repos.RepositoryException;
@@ -185,6 +186,11 @@
if (location.isPostgresqlProtocol()) {
logger.info("postgres database " + location.getDatabase());
_accessPoint = new PostgresAccessPoint(location.getDatabase());
+ return _accessPoint;
+ }
+ if (location.isOracleProtocol()) {
+ logger.info("oracle database " + location.getDatabase());
+ _accessPoint = new OracleAccessPoint(location.getList());
return _accessPoint;
}
else if (location.isDatabusProtocol()) {
Index: org/eclipse/stellation/workspace/Location.java
===================================================================
RCS file: /home/technology/org.eclipse.stellation/plugins/org.eclipse.stellation.core/src/org/eclipse/stellation/workspace/Location.java,v
retrieving revision 1.6
diff -u -r1.6 Location.java
--- org/eclipse/stellation/workspace/Location.java 19 Jul 2002 17:40:17 -0000 1.6
+++ org/eclipse/stellation/workspace/Location.java 24 Jul 2002 09:28:43 -0000
@@ -38,7 +38,8 @@
Selector protocolSelector = new Selector()
.add("db2")
.add("remote")
- .add("postgresql");
+ .add("postgresql")
+ .add("oracle");
_protocol = protocolSelector.select(arg);
if (! _protocol.startsWith("=")) {
System.err.println("invalid protocol name " + arg);
@@ -144,6 +145,16 @@
*/
public boolean isPostgresqlProtocol() {
return _protocol.equals("postgresql");
+ }
+
+ /**
+ * Tests if the protocol is Oracle
+ *
+ * @return <code>true</code> if and only if the location protocol
+ * is Databus.
+ */
+ public boolean isOracleProtocol() {
+ return _protocol.equals("oracle");
}
/**