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 Servletweb.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の処理を分析します.