hsqldbソース分析起動デバッグ

9291 ワード


 hsqldbはjava版の簡略化されたデータベースで、コード量は比較的少ないです.データベースの設計を学ぶにはいい選択です.
Debyコードの量が大きいので、mysql c++はもっと複雑です.だからhsqldbを勉強してデータベースのデザインを勉強します.
ここでソースをダウンロードできます.http://hsqldb.org/ソースコードの下にorg.hsqldb.testテストの種類がたくさんあります.ここからテスト勉強を始めてもいいです.
 
Hyper SQL データベースの名前はcatalogで、データベースの保存方式によっていくつかに分けられます.
•mem:stored entirely in RAM-without any persistence beyond the JVM process's life•file:stored in filesystem files
•res:stored in a Java reource、such as a Jar and always read-only
 
クライアントは、接続列によって異なる記憶フォーマットを指定することができます.
 
 Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "SA", "");
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");file:       
 Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");mem           
  Connection c = DriverManager.getConnection("jdbc:hsqldb:res:org.my.path.resdb", "SA", ""); res      classpath java  zip  ,      
 
hyperSQLのサーバモードを起動します.
HyperSQL HSQL Server パラメータ--helpを使ってパラメータオプションを確認できます.以下はmydbデータファイルを開いてデータベースの別名としてxdbとなります.クライアントはxdbデータベースを使ってサーバーに接続して使用できます.
java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb
 HyperSQL HTTP Server httpプロトコルのサーバモード
java -cp ../lib/hsqldb.jar org.hsqldb.server.WebServer --database.0 file:mydb --dbname.0 xdb
 servlet容器起動サーバHyperSQL HTTP Servlet
web.xmlにorg/hsqldb/server/Servlet.javaというservletを配置する必要があります.このモードは一つのデータベースしかサポートできません.
クライアントはhsql serverに接続されています.
 try {
      Class.forName("org.hsqldb.jdbc.JDBCDriver" );
  } catch (Exception e) {
      System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
      e.printStackTrace();
      return;
  }
 
 Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "SA", "");
   hsql       :hsql:,http  http://
  Connection c = DriverManager.getConnection("jdbc:hsqldb:http://localhost/xdb", "SA", "");

  ssl   hsql  http    
 Connection c = DriverManager.getConnection("jdbc:hsqldb:hsqls://localhost/xdb", "SA", "");
 Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost/xdb", "SA", "");
 
     :    shutdown=true,                 ,          (      , flush   ),             。
  Connection c = DriverManager.getConnection(
          "jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");

           ,    ifexists=true,        ,    。
Connection c = DriverManager.getConnection(
        "jdbc:hsqldb:file:/opt/db/testdb;ifexists=true", "SA", "");
 
コード解析:
  org.hsqldb.server類のrun方法は入力を処理して、データベースを開けて、サーバーのsocketあるいはhttp接続を創立して、socket接続を傍受して、毎回accept一つのsocketは接続して、public void handleConnection(Socket s)の方法を使ってこの接続を処理して、各クライアントはサービス端末に接続して一つのスレッドを生産して処理して、処理します.その後、各ServerConnectionまたはWebServer Connectionで各sqlの処理を処理し、後でsqlのアクセスプロトコルをさらに分析し、後でsql文法分析、意味分析などの後続ロジックを分析する.このコードは比較的簡単で、皆さんは直接server類を見ることができます.
  重要な部分は以下の通りです.
 public void handleConnection(Socket s) {


        Thread   t;
        Runnable r;
        String   ctn;


        printWithThread("handleConnection(" + s + ") entered");


        if (!allowConnection(s)) {
            try {
                s.close();
            } catch (Exception e) {}


            printWithThread("allowConnection(): connection refused");
            printWithThread("handleConnection() exited");


            return;
        }


        // Maybe set up socket options, SSL
        // Session tracing/callbacks, etc.
        if (socketFactory != null) {
            socketFactory.configureSocket(s);
        }


        if (serverProtocol == ServerConstants.SC_PROTOCOL_HSQL) {
            r   = new ServerConnection(s, this);
            ctn = ((ServerConnection) r).getConnectionThreadName();
        } else {
            r   = new WebServerConnection(s, (WebServer) this);
            ctn = ((WebServerConnection) r).getConnectionThreadName();
        }


        t = new Thread(serverConnectionThreadGroup, r, ctn);


        t.start();
        printWithThread("handleConnection() exited");
    }
 
 serverのmain関数からの出力パラメータは主にいくつかあります.maxConnectionの最大接続数に制限があります. isSilentがすべてのqueryを表示しているかどうか、isRemoteOpenがリモートオープンをサポートしているかどうか、サポートしていないか、isDaemenが守護モードかどうか、aclがアクセス制御権限ファイルのパスを指定し、ipアドレスのモノクロリストを指定します.aclファイルフォーマット参照http://hsqldb.org/doc/2.0/guide/listeners-chapt.html#N15C79
 * +-----------------+-------------+----------+------------------------------+
 * |    OPTION       |    TYPE     | DEFAULT  |         DESCRIPTION          |
 * +-----------------+-------------+----------+------------------------------|
 * | --help          |             |          | prints this message          |
 * | --address       | name|number | any      | server inet address          |
 * | --port          | number      | 9001/544 | port at which server listens |
 * | --database.i    | [type]spec  | 0=test   | path of database i           |
 * | --dbname.i      | alias       |          | url alias for database i     |
 * | --silent        | true|false  | true     | false => display all queries |
 * | --trace         | true|false  | false    | display JDBC trace messages  |
 * | --tls           | true|false  | false    | TLS/SSL (secure) sockets     |
 * | --no_system_exit| true|false  | false    | do not issue System.exit()   |
 * | --remote_open   | true|false  | false    | can open databases remotely  |
 * | --props         | filepath    |          | file path of properties file |
 * +-----------------+-------------+----------+------------------------------+
 
    maxConnections = serverProperties.getIntegerProperty(
            ServerProperties.sc_key_max_connections, 16);

        JavaSystem.setLogToSystem(isTrace());

        isSilent =
            serverProperties.isPropertyTrue(ServerProperties.sc_key_silent);
        isRemoteOpen = serverProperties.isPropertyTrue(
            ServerProperties.sc_key_remote_open_db);
        isDaemon =
            serverProperties.isPropertyTrue(ServerProperties.sc_key_daemon);
 もちろんopenDatabaseの中にはパラメータによって指定されたdatabaseファイルに対応するデータベースを開きます.
database類のreopen方法にはいくつかのオブジェクトがあります.データベース操作に関するオブジェクトは、データベースオブジェクト名管理、権限管理、ユーザー管理、shema管理、session管理、事務管理、ログ管理、チェックポイント管理、次の分析にほかならないです.
  /**
     * Opens this database.  The database should be opened after construction.
     * or reopened by the close(int closemode) method during a
     * "shutdown compact". Closes the log if there is an error.
     */
    void reopen() {

        boolean isNew = false;

        setState(DATABASE_OPENING);

        try {
            nameManager    = new HsqlNameManager(this);
            granteeManager = new GranteeManager(this);
            userManager    = new UserManager(this);
            schemaManager  = new SchemaManager(this);
            persistentStoreCollection =
                new PersistentStoreCollectionDatabase();
            isReferentialIntegrity = true;
            sessionManager         = new SessionManager(this);
            collation              = collation.newDatabaseInstance();
            dbInfo = DatabaseInformation.newDatabaseInformation(this);
            txManager              = new TransactionManager2PL(this);

            lobManager.createSchema();
            sessionManager.getSysLobSession().setSchema(
                SqlInvariants.LOBS_SCHEMA);
            schemaManager.setSchemaChangeTimestamp();
            schemaManager.createSystemTables();

            // completed metadata
            logger.openPersistence();

            isNew = logger.isNewDatabase;

            if (isNew) {
                String username = urlProperties.getProperty("user", "SA");
                String password = urlProperties.getProperty("password", "");

                userManager.createFirstUser(username, password);
                schemaManager.createPublicSchema();
                lobManager.initialiseLobSpace();
                logger.checkpoint(false);
            }

            lobManager.open();
            dbInfo.setWithContent(true);

            checkpointRunner = new CheckpointRunner();
        } catch (Throwable e) {
            logger.closePersistence(Database.CLOSEMODE_IMMEDIATELY);
            logger.releaseLock();
            setState(DATABASE_SHUTDOWN);
            clearStructures();
            DatabaseManager.removeDatabase(this);

            if (!(e instanceof HsqlException)) {
                e = Error.error(ErrorCode.GENERAL_ERROR, e);
            }

            logger.logSevereEvent("could not reopen database", e);

            throw (HsqlException) e;
        }

        setState(DATABASE_ONLINE);
    }
 
次のセクションでは、handleConnectionの処理を分析します.