/__w/shurbej/shurbej/_build/test/cover/ct/shurbej_db_schema.html

1 -module(shurbej_db_schema).
2 -include("shurbej_records.hrl").
3
4 -export([ensure/0, current_version/0]).
5
6 %% Bump this when records change, keys change shape, or tables get
7 %% added/removed in a way that would misalign an older on-disk copy.
8 -define(SCHEMA_VERSION, 1).
9
10
:-(
current_version() -> ?SCHEMA_VERSION.
11
12 ensure() ->
13 1 ensure_schema(),
14 1 ensure_tables(),
15 1 check_schema_version(),
16 1 check_users(),
17 1 ok.
18
19 ensure_schema() ->
20 1 mnesia:stop(),
21 1 Node = node(),
22 1 case mnesia:create_schema([Node]) of
23 1 ok -> ok;
24
:-(
{error, {Node, {already_exists, Node}}} -> ok
25 end,
26 1 ok = mnesia:start().
27
28 ensure_tables() ->
29 1 StorageType = case node() of
30 1 nonode@nohost -> ram_copies;
31
:-(
_ -> disc_copies
32 end,
33 1 Tables = [
34 {shurbej_schema_meta, record_info(fields, shurbej_schema_meta), set, []},
35 {shurbej_library, record_info(fields, shurbej_library), set, []},
36 {shurbej_api_key, record_info(fields, shurbej_api_key), set, []},
37 {shurbej_item, record_info(fields, shurbej_item), set, [parent_key]},
38 {shurbej_collection, record_info(fields, shurbej_collection), set, []},
39 {shurbej_search, record_info(fields, shurbej_search), set, []},
40 {shurbej_tag, record_info(fields, shurbej_tag), set, []},
41 {shurbej_setting, record_info(fields, shurbej_setting), set, []},
42 {shurbej_deleted, record_info(fields, shurbej_deleted), set, []},
43 {shurbej_fulltext, record_info(fields, shurbej_fulltext), set, []},
44 {shurbej_file_meta, record_info(fields, shurbej_file_meta), set, []},
45 {shurbej_blob, record_info(fields, shurbej_blob), set, []},
46 {shurbej_user, record_info(fields, shurbej_user), set, []},
47 {shurbej_item_collection, record_info(fields, shurbej_item_collection), bag, []},
48 {shurbej_group, record_info(fields, shurbej_group), set, [owner_id]},
49 {shurbej_group_member, record_info(fields, shurbej_group_member), set, []}
50 ],
51 1 lists:foreach(fun({Name, Fields, Type, Indices}) ->
52 16 case mnesia:create_table(Name, [
53 {attributes, Fields},
54 {type, Type},
55 {StorageType, [node()]}
56 2 | [{index, Indices} || Indices =/= []]
57 ]) of
58 16 {atomic, ok} -> ok;
59
:-(
{aborted, {already_exists, Name}} -> ok
60 end
61 end, Tables),
62 1 ok = mnesia:wait_for_tables(
63 [shurbej_schema_meta, shurbej_library, shurbej_api_key, shurbej_item,
64 shurbej_collection, shurbej_search, shurbej_tag, shurbej_setting,
65 shurbej_deleted, shurbej_fulltext, shurbej_file_meta, shurbej_blob,
66 shurbej_user, shurbej_item_collection, shurbej_group,
67 shurbej_group_member],
68 5000
69 ).
70
71 %% Compare on-disk schema version with the compiled constant. On a fresh
72 %% install, stamp the sentinel row. On mismatch, abort startup: silently
73 %% running against an incompatible on-disk layout can corrupt data.
74 check_schema_version() ->
75 1 case mnesia:dirty_read(shurbej_schema_meta, version) of
76 [] ->
77 1 mnesia:dirty_write(#shurbej_schema_meta{
78 key = version, value = ?SCHEMA_VERSION
79 }),
80 1 ok;
81 [#shurbej_schema_meta{value = ?SCHEMA_VERSION}] ->
82
:-(
ok;
83 [#shurbej_schema_meta{value = OnDisk}] ->
84
:-(
Msg = io_lib:format(
85 "schema version mismatch: on-disk=~p, compiled=~p. "
86 "Migrate or wipe the mnesia dir before starting.",
87 [OnDisk, ?SCHEMA_VERSION]),
88
:-(
logger:error("~s", [Msg]),
89
:-(
erlang:error({schema_version_mismatch, OnDisk, ?SCHEMA_VERSION})
90 end.
91
92 check_users() ->
93 1 case mnesia:dirty_first(shurbej_user) of
94 '$end_of_table' ->
95 1 logger:notice("no users configured. "
96 "Create one with: shurbej_admin:create_user(<<\"username\">>, <<\"password\">>, 1).");
97 _ ->
98
:-(
ok
99 end.
Line Hits Source