Erlang 聊天室程序(九) 主题房间2 ---房间信息管理

         接着上一篇,这次处理“维护当前可用的主题房间信息”问题。 每次使用startChild启动子进程的时候将当前的房间信息保存到ets表中。更重要的是每次主题房异常退出或重启都要更新对应的信息。

         修改room_manager.erl中的内容:

新建一个函数来初始化房间信息表:

initTab()->
        ets: new(roominfo,[ public,
             ordered_set,
             named_table,
            {keypos,#roominfo.id}
        ])
.

 再添加对房间表数据操作的方法:

addRoomInfo(Record)->
    #roominfo{name=Name,type=Type}=Record,
     case isRoomUniq([],Name,Type)of
        {found,_Id}->
            {fail,room_exists};
        {not_found}->            
            RoomId=id_generator:getnewid("room"),
            ClientTableName=list_to_atom(?PRIFIX++integer_to_list(RoomId)),
            Info=Record#roominfo{id=RoomId,tablename=ClientTableName},        
            ets:insert(roominfo, Info),
            {success,Info}
    end
.

setRoomAvailble(Id)->
     case ets:lookup(roominfo, Id) of
        Record->
            ets:update_element(roominfo, Id, {#roominfo.status,1}),
            ok;
        []->
            ok
    end
.

setRoomUnavailble(Id)->
     case ets:lookup(roominfo, Id) of
        Record->
            ets:update_element(roominfo, Id, {#roominfo.status,0}),
            ok;
        []->
            ok
    end
.
removeRoom(Id)->
    ets:delete(roominfo, Id)
.

 为了方便后面的操作,再提供两个方法,一个根据给定的属性获取对应的ID,一个是判断对应ID的房间是否存在:

getRoomProperty(Id,Proper)->
     case ets:lookup(roominfo, Id) of
        Record->
            #roominfo{name=Name,
                      type=Type,
                      unum=Unum,
                      tablename=Tab,
                      status=Status,
                      creationDate=Crdate}=Record,            
             case Proper of
                #roominfo.name->
                    {ok,Name};
                #roominfo.type->
                    {ok,Type};
                #roominfo.unum->
                    {ok,Unum};
                #roominfo.tablename->
                    {ok,Tab};
                #roominfo.status->
                    {ok,Status};
                #roominfo.creationDate->
                    {ok,Crdate};
                _Els->
                    {fail,illegal_property}
            end;        
        _Els->
            {fail,not_found}
    end    
.

isRoomUniq([],Name,Type)->
     case ets:all(roominfo) of
        [R|L]->
            #roominfo{id=Id,name=TheName,type=TheType}=R,
             case string:equal("Name",TheName) and string:equal(Type, TheType) of
                 true->
                    {found,Id};
                 false->
                    isRoomUniq([L],Name,Type)        
            end;
        []->
            {not_found}
    end
;
isRoomUniq([L],Name,Type)->
     case ets:all(roominfo) of
        [R|L]->
            #roominfo{id=Id,name=TheName,type=TheType}=R,
             case string:equal("Name",TheName) and string:equal(Type, TheType) of
                 true->
                    {found,Id};
                 false->
                    isRoomUniq([L],Name,Type)        
            end;
        []->
            {not_found}
    end
.

     再修改chat_room的terminate,从表中删除相应的记录:

 

terminate(_Reason,State)->
    #roominfo{id=Id}=State,
    room_manager:removeRoom(Id)
.

    再修改房间启动时的初始化方法,房间的ID和名称从外部传入:

init([Para])->
    id_generator:start_link(), 
    #roominfo{id=RoomId,tablename=ClientTableName}=Para,
    client_manager:init(ClientTableName),
     case is_record(Para,roominfo)of
         true->
            {ok,#roominfo{unum=0}=Para,tablename=ClientTableName};
        Els->                        
            {ok,#roominfo{id=RoomId,unum=0,name="room"++integer_to_list(RoomId),tablename=ClientTableName,type="def"}}
    end
.

     暂时不对代码进行测试,等后面整体修改完成后再一起测。

 

 

 

你可能感兴趣的:(erlang)