首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

MongoDB Java Driver 源码分析(五):com.mongodb.DB

2012-08-16 
MongoDB Java Driver 源码分析(5):com.mongodb.DBDB 表示数据库连接,是一个抽象类,部分核心功能由子类提供

MongoDB Java Driver 源码分析(5):com.mongodb.DB
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 ));    }

热点排行