最近在研究ChicagoBoss框架,在网上找到的资料基本上都是github里的readme篇幅,还有就是官方的一些文档。迫于无奈只能去看源码,以下是我读里源码后的理解: 获取ChicagoBoss源码 git clone https://github.com/ChicagoBoss/ChicagoBoss.git cd ChicagoBoss/ make || ./rebar g-d && ./rebar co 首先先查看下README.md和READMEs,里面有一些相关的介绍,数据库配置之类的。 根据README.md,首先创建自己的第一个ChicagoBoss项目 make app PROJECT=mycb cd ../mycb ./init-dev.sh %%% 启动项目 查看src的目录结构如图:
关于这些结构的介绍可以查看官网上的新手文档:chicagoboss.org/tutorial.pd… github.com/ChicagoBoss… 下面我记录的是关于数据库配置的: boss.config 默认情况下,项目中的存储是由一个叫mock的adapter负责,查看源码才知道,所谓的mock就是进程字典,见源码: boss_db_mock_controller.erl save_record
NewRecord = Record:set(NewAttributes),
{reply, NewRecord, [{dict:store(Id, NewRecord, Dict), IdCounter1}|OldState]};
复制代码
在boss_db_controller.erl中的save_record,
{Adapter, _, Conn} = db_for_record(Record, State),
{reply, Adapter:save_record(Conn, Record), State};
复制代码
这里的Adapter取值为boss_db_adapter_(DatabaseType):
dynymodb,mnesia,mock, mongodb,mysql,pgsql, riak等。
复制代码
下面是boss_db_adapter_mock.erl的保存记录的函数
save_record(_, Record) ->
SavedRecord = gen_server:call({global, boss_db_mock}, {save_record, Record}),
{ok, SavedRecord}.
复制代码
通过poolboy找到boss_db_mock_controller.erl,完成存储。 ChicagoBoss的id有两种,一种是自增的,一种是uuid,见源码
{Id, IdCounter1} = case Record:id() of
id -> case boss_sql_lib:keytype(Record) of
uuid -> {lists:concat([Type, "-", uuid:to_string(uuid:uuid4())]), IdCounter};
_ -> {lists:concat([Type, "-", IdCounter]), IdCounter + 1}
end;
ExistingId ->
case boss_sql_lib:keytype(Record) of
uuid -> {ExistingId, IdCounter};
_ ->
[TypeString, IdNum] = string:tokens(ExistingId, "-"),
Max = case list_to_integer(IdNum) of
N when N > IdCounter -> N;
_ -> IdCounter
end,
{lists:concat([Type, "-", IdNum]), Max + 1}
end
end,
复制代码
boss_db_controller.erl模块有#state{},
-record(state, {
connection_state,
connection_delay,
connection_retry_timer,
options,
adapter,
read_connection,
write_connection,
shards = [],
model_dict = dict:new(),
cache_enable,
cache_ttl,
cache_prefix,
depth = 0}).
复制代码
其中cache_enable意为是否缓存,cache_ttl为缓存时间, 缓存默认是不开启的,如果开启,但是没有设置缓存数据库的话,默认是mock,即字典进程, EX:设置缓存为redis,boss.config设置如下:
{cache_adapter, redis},
{cache_enable, true},
{db_cache_enable, true},
{cache_servers, [
{host, "127.0.0.1"},
{port, 6379},
{pass, undefined},
{db, 0},
{reconnect, true}]},
复制代码
只有同时设置里cache_enable和db_cache_enable为true,其他数据库才会存入缓存,见源码: boss_model_manager_boss_db.erl
DBCacheEnable = boss_env:get_env(db_cache_enable, false) andalso CacheEnable,
复制代码
但是这些缓存的设置只是在查询时有效,也就是说,在查询是在缓存查不到数据,再转到数据库查找,找到之后存入缓存,并设置过期时间。 在redis部分,源码存在bug: boss_cache_adapter_redis.erl
get(Conn, Prefix, Key) ->
case redo:cmd(Conn,["GET", term_to_key(Prefix, Key)]) of
Bin ->
binary_to_term(Bin)
end.
复制代码
当查找不到时Bin = undefined,此时binary_to_term(undeinfed)会报错, 修改为 :
get(Conn, Prefix, Key) ->
case redo:cmd(Conn,["GET", term_to_key(Prefix, Key)]) of
undefined ->
undefined;
Bin ->
binary_to_term(Bin)
end.
复制代码
mysql部分的配置如下:
{db_shards, [
[
{db_host, "localhost"},
{db_adapter, mysql},
{db_port, 3306},
{db_username, "root"},
{db_password, ""},
{db_database, "cb_mysql"},
{db_shard_id, cb_mysql},
{db_shard_models, [my_data]}
]
]},
复制代码
db_shard_models是模块名,需要为这个模块创建数据库my_datas,,没错,是复数形式。db_adapter表示的是哪个数据库适配器调用,这里是boss_db_adapter_mysql,关于controller,view,model等,看完新手引导,就差不多了。