Skip to main content

[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");
     }
 
     /**

Back to the top