kvs_fs.erl 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. -module(kvs_fs).
  2. -include("backend.hrl").
  3. -include("kvs.hrl").
  4. -include("metainfo.hrl").
  5. -include_lib("stdlib/include/qlc.hrl").
  6. -export(?BACKEND).
  7. start() -> ok.
  8. stop() -> ok.
  9. destroy() -> ok.
  10. version() -> {version,"KVS FS"}.
  11. leave() -> ok.
  12. dir() -> [ {table,F} || F <- filelib:wildcard("data/*"), filelib:is_dir(F) ].
  13. join(_Node) -> filelib:ensure_dir("data/"), initialize(). % should be rsync or smth
  14. initialize() ->
  15. mnesia:create_schema([node()]),
  16. [ kvs:initialize(kvs_fs,Module) || Module <- kvs:modules() ],
  17. mnesia:wait_for_tables([ T#table.name || T <- kvs:tables()],infinity).
  18. index(_Tab,_Key,_Value) -> [].
  19. get(TableName, Key) ->
  20. HashKey = encode(base64:encode(crypto:hash(sha, term_to_binary(Key)))),
  21. Dir = lists:concat(["data/",TableName,"/"]),
  22. case file:read_file(lists:concat([Dir,HashKey])) of
  23. {ok,Binary} -> {ok,binary_to_term(Binary,[safe])};
  24. {error,Reason} -> {error,Reason} end.
  25. put(Records) when is_list(Records) -> lists:map(fun(Record) -> put(Record) end, Records);
  26. put(Record) ->
  27. TableName = element(1,Record),
  28. HashKey = encode(base64:encode(crypto:hash(sha, term_to_binary(element(2,Record))))),
  29. BinaryValue = term_to_binary(Record),
  30. Dir = lists:concat(["data/",TableName,"/"]),
  31. filelib:ensure_dir(Dir),
  32. File = lists:concat([Dir,HashKey]),
  33. file:write_file(File,BinaryValue,[write,raw,binary,sync]).
  34. delete(_Tab, _Key) -> case kvs:get(_Tab,_Key) of {ok,_} -> ok; {error,X} -> {error,X} end.
  35. count(RecordName) -> length(filelib:fold_files(lists:concat(["data/",RecordName]), "",true, fun(A,Acc)-> [A|Acc] end, [])).
  36. all(R) -> lists:flatten([ begin case file:read_file(File) of
  37. {ok,Binary} -> binary_to_term(Binary,[safe]);
  38. {error,_Reason} -> [] end end || File <-
  39. filelib:fold_files(lists:concat(["data/",R]), "",true, fun(A,Acc)-> [A|Acc] end, []) ]).
  40. seq(RecordName, Incr) -> kvs_mnesia:seq(RecordName, Incr).
  41. create_table(Name,_Options) -> filelib:ensure_dir(lists:concat(["data/",Name,"/"])).
  42. add_table_index(_Record, _Field) -> ok.
  43. % URL ENCODE
  44. encode(B) when is_binary(B) -> encode(binary_to_list(B));
  45. encode([C | Cs]) when C >= $a, C =< $z -> [C | encode(Cs)];
  46. encode([C | Cs]) when C >= $A, C =< $Z -> [C | encode(Cs)];
  47. encode([C | Cs]) when C >= $0, C =< $9 -> [C | encode(Cs)];
  48. encode([C | Cs]) when C == 16#20 -> [$+ | encode(Cs)];
  49. % unreserved
  50. encode([C = $- | Cs]) -> [C | encode(Cs)];
  51. encode([C = $_ | Cs]) -> [C | encode(Cs)];
  52. encode([C = 46 | Cs]) -> [C | encode(Cs)];
  53. encode([C = $! | Cs]) -> [C | encode(Cs)];
  54. encode([C = $~ | Cs]) -> [C | encode(Cs)];
  55. encode([C = $* | Cs]) -> [C | encode(Cs)];
  56. encode([C = 39 | Cs]) -> [C | encode(Cs)];
  57. encode([C = $( | Cs]) -> [C | encode(Cs)];
  58. encode([C = $) | Cs]) -> [C | encode(Cs)];
  59. encode([C | Cs]) when C =< 16#7f -> escape_byte(C) ++ encode(Cs);
  60. encode([C | Cs]) when (C >= 16#7f) and (C =< 16#07FF) ->
  61. escape_byte((C bsr 6) + 16#c0)
  62. ++ escape_byte(C band 16#3f + 16#80)
  63. ++ encode(Cs);
  64. encode([C | Cs]) when (C > 16#07FF) ->
  65. escape_byte((C bsr 12) + 16#e0) % (0xe0 | C >> 12)
  66. ++ escape_byte((16#3f band (C bsr 6)) + 16#80) % 0x80 | ((C >> 6) & 0x3f)
  67. ++ escape_byte(C band 16#3f + 16#80) % 0x80 | (C >> 0x3f)
  68. ++ encode(Cs);
  69. encode([C | Cs]) -> escape_byte(C) ++ encode(Cs);
  70. encode([]) -> [].
  71. hex_octet(N) when N =< 9 -> [$0 + N];
  72. hex_octet(N) when N > 15 -> hex_octet(N bsr 4) ++ hex_octet(N band 15);
  73. hex_octet(N) -> [N - 10 + $a].
  74. escape_byte(C) -> normalize(hex_octet(C)).
  75. normalize(H) when length(H) == 1 -> "%0" ++ H;
  76. normalize(H) -> "%" ++ H.
  77. dump() -> ok.