我的家園

          我的家園
          DB 表示數據庫連接,是一個抽象類,部分核心功能由子類提供,由 DBApiLayer 繼承。

          由子類實現的抽象方法

          // 開始數據庫連接
          public abstract void requestStart();
          // 結束數據庫連接
          public abstract void requestDone();
          // 保持數據庫連接
          public abstract void requestEnsureConnection();
          
          // 獲取指定名稱的數據集
          protected abstract DBCollection doGetCollection( String name );
          


          數據集相關的方法

              // 創建數據集
              public final DBCollection createCollection( String name, DBObject options ){
                  // 如果 options 不為空
                  // 則先以 options 構造創建數據庫的命令
                  // 然后執行創建數據庫的命令并得到結果
                  if ( options != null ){
                      DBObject createCmd = new BasicDBObject("create", name);
                      createCmd.putAll(options);
                      CommandResult result = command(createCmd);
                      result.throwOnError();
                  }
          
                  return getCollection(name);
              }
          
              // 解析用 "." 分隔的字符串,獲取指定的數據集
              public DBCollection getCollectionFromString( String s ){
                  DBCollection foo = null;
          
                  // 獲取 "." 所在位置
                  int idx = s.indexOf( "." );
          
                  // 當分解后的字符串中仍然包含 "." 時
                  // 循環分解字符串,知道所有 "." 號解析完畢
                  // 效果類似于遞歸調用,但這里采用了循環的寫法
                  while ( idx >= 0 ){
                      // 獲取 "." 之前的字符串 b
                      String b = s.substring( 0 , idx );
                      // 獲取 "." 之后的字符串 s
                      s = s.substring( idx + 1 );
          
                      // 檢查上次解析得到的對象 foo 是否為空
                      if ( foo == null )
                          foo = getCollection( b );
                      else
                          foo = foo.getCollection( b );
          
                      // 獲取 "." 所在位置
                      idx = s.indexOf( "." );
                  }
          
                  if ( foo != null )
                      return foo.getCollection( s );
          
                  return getCollection( s );
              }
          
              // 獲取所有數據集名稱
              public Set<String> getCollectionNames()
                  throws MongoException {
          
                  // 獲取系統的 namespace 數據集
                  DBCollection namespaces = getCollection("system.namespaces");
                  if (namespaces == null)
                      throw new RuntimeException("this is impossible");
          
                  // 獲取用于遍歷 namespace 的迭代器
                  Iterator<DBObject> i = namespaces.__find(new BasicDBObject(), null, 0, 0, 0, getOptions());
                  if (i == null)
                      return new HashSet<String>();
          
                  // 表名稱 List,最后轉換為 set 并返回
                  List<String> tables = new ArrayList<String>();
          
                  for (; i.hasNext();) {
                      DBObject o = i.next();
                      if ( o.get( "name" ) == null ){
                          throw new MongoException( "how is name null : " + o );
                      }
          
                      // 獲取 namespace 名稱
                      String n = o.get("name").toString();
          
                      // 獲取 namespace 名稱前綴
                      int idx = n.indexOf(".");
                      String root = n.substring(0, idx);
          
                      // 如果前綴不為當前 DB 的名稱
                      // 表示這個 namespace 不屬于當前 DB
                      if (!root.equals(_name))
                          continue;
          
                      // 忽略特殊數據集
                      if (n.indexOf("$") >= 0)
                          continue;
          
                      // 獲取數據集名稱
                      String table = n.substring(idx + 1);
          
                      tables.add(table);
                  }
          
                  Collections.sort(tables);
          
                  // 轉換為 Set
                  return new LinkedHashSet<String>(tables);
              }
          


          數據庫命令相關的方法

              // 執行數據庫命令
              public CommandResult command( DBObject cmd , int options )
                  throws MongoException {
          
                  // 調用 DBCollection 的 find 方法        
                  Iterator<DBObject> i = getCollection("$cmd").__find(cmd, new BasicDBObject(), 0, -1, 0, options);
                  if ( i == null || ! i.hasNext() )
                      return null;
           
                  // 獲得數據庫命令的返回結果結果       
                  CommandResult res = (CommandResult)i.next();
                  res._cmd = cmd;
                  return res;
              }
          
              // 以 "eval" 方式解析命令
              public CommandResult doEval( String code , Object ... args )
                  throws MongoException {
          
                  // 構造 "eval" 命令
                  // 調用 command 方法執行并獲得結果
                  return command( BasicDBObjectBuilder.start()
                                  .add( "$eval" , code )
                                  .add( "args" , args )
                                  .get() );
              }
          
              // 刪除數據庫
              public void dropDatabase()
                  throws MongoException {
          
                  CommandResult res = command(new BasicDBObject("dropDatabase", 1));
                  res.throwOnError();
                  _mongo._dbs.remove(this.getName());
              }
          


          用戶相關的方法

              // 驗證用戶名和密碼
              public CommandResult authenticateCommand(String username, char[] passwd )
                  throws MongoException {
          
                  if ( username == null || passwd == null )
                      throw new NullPointerException( "username can't be null" );
          
                  if ( _username != null )
          	    throw new IllegalStateException( "can't call authenticate twice on the same DBObject" );
          
                  // 根據用戶名和密碼,通過 MD5 計算哈希值 
                  String hash = _hash( username , passwd );
          
                  // 驗證用戶名和密碼并獲得返回結果
                  CommandResult res = _doauth( username , hash.getBytes() );
                  res.throwOnError();
                  _username = username;
                  _authhash = hash.getBytes();
                  return res;
              }
          
              // 驗證用戶名和密碼并獲得返回結果
              private CommandResult _doauth( String username , byte[] hash ){
                  // 獲取 "鹽值",用于加密
                  CommandResult res = command(new BasicDBObject("getnonce", 1), getOptions());
                  res.throwOnError();
          
                  // 利用當前的用戶名和密碼,執行一個沒有實際意義的操作
                  // 利用 username, 加密后的密碼,以及鹽值進行驗證,看看是否產生錯誤
                  DBObject cmd = _authCommand( res.getString( "nonce" ) , username , hash );
                  return command(cmd, getOptions());
              }
          
          
              // 利用 username, 加密后的密碼,以及鹽值進行驗證,看看是否產生錯誤
              static DBObject _authCommand( String nonce , String username , byte[] hash ){
                  // 獲取由 username, 加密后的密碼,以及鹽值 組成的 key
                  String key = nonce + username + new String( hash );
          
                  // 構造用于驗證用戶的命令
                  BasicDBObject cmd = new BasicDBObject();
          
                  cmd.put("authenticate", 1);
                  cmd.put("user", username);
                  cmd.put("nonce", nonce);
          
                  // 對 key 進行 MD5 加密
                  cmd.put("key", Util.hexMD5(key.getBytes()));
                  
                  return cmd;
              }
          
              // 添加用戶
              public WriteResult addUser( String username , char[] passwd, boolean readOnly ){
                  // 獲取系統用戶
                  DBCollection c = getCollection( "system.users" );
          
                  // 根據指定的 username 獲取用戶
                  DBObject o = c.findOne( new BasicDBObject( "user" , username ) );
                  // 如果不存在,則創建
                  if ( o == null )
                      o = new BasicDBObject( "user" , username );
          
                  // 設置密碼
                  o.put( "pwd" , _hash( username , passwd ) );
                  // 設置只讀權限
                  o.put( "readOnly" , readOnly );
          
                  // 將構造出來的用戶對象添加到 系統用戶數據集 中
                  return c.save( o );
              }
          
              // 刪除用戶
              public WriteResult removeUser( String username ){
                  DBCollection c = getCollection( "system.users" );
                  return c.remove(new BasicDBObject( "user" , username ));
              }
          





          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 长宁县| 南充市| 桂林市| 札达县| 天柱县| 上蔡县| 岚皋县| 浦城县| 西充县| 漾濞| 太谷县| 齐河县| 永清县| 嘉禾县| 横山县| 小金县| 都匀市| 盈江县| 云安县| 林芝县| 绥棱县| 阿拉善盟| 安吉县| 宁武县| 娄烦县| 甘泉县| 宾阳县| 磐安县| 满洲里市| 论坛| 高雄县| 凯里市| 含山县| 乌什县| 万安县| 贡山| 赤峰市| 云安县| 清原| 山西省| 砀山县|