-
Notifications
You must be signed in to change notification settings - Fork 9
/
article_history.erl
91 lines (78 loc) · 3.13 KB
/
article_history.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%% http://www.apache.org/licenses/LICENSE-2.0
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%% @doc Convenience functions around article history.
%% @author Bryan Fink <bryan@basho.com>
%% @copyright 2009 Basho Technologies, Inc. All Rights Reserved.
-module(article_history).
-export([add_version/2,
get_version_summaries/1]).
-include("wriaki.hrl").
%% @spec add_version(wriaki:article()) -> ok
%% @doc Update the history object for Article with an
%% entry for the revision contained in Article.
add_version(Client, Article) ->
{ok, Hist} = fetch_or_new(Client, rec_obj:key(Article)),
rhc:put(Client,
rec_obj:add_link(Hist,
{{?B_ARCHIVE,
article:archive_key(Article)},
date_string(article:get_timestamp(Article))})).
date_string(TS) ->
integer_to_list(TS).
fetch_or_new(Client, Key) ->
case rhc:get(Client, ?B_HISTORY, Key) of
{ok, H} ->
case rec_obj:has_siblings(H) of
true ->
{ok, merge_siblings(rec_obj:get_siblings(H))};
false ->
{ok, H}
end;
{error, notfound} ->
{ok, rec_obj:create(?B_HISTORY, Key, <<>>)}
end.
merge_siblings(Siblings) ->
lists:foldl(fun merge_links/2, hd(Siblings), tl(Siblings)).
merge_links(Obj, Acc) ->
lists:foldl(fun(L, A) -> rec_obj:add_link(A, L) end,
Acc,
rec_obj:get_links(Obj)).
-define(TIME_ORDER,
iolist_to_binary(
[<<"function(v) {\n">>,
<<"return v.sort(\n">>,
<<"function(a,b) { return b[2]-a[2]; }\n">>,
<<"); }">>])).
-define(SUMMARY_EXTRACTION,
iolist_to_binary(
[<<"function(v) {\n">>,
<<"var json = JSON.parse(v.values[0].data);\n">>,
<<"var summary = {\n">>,
<<"version: json.version,\n">>,
<<"timestamp: json.timestamp,\n">>,
<<"message: json.message,\n">>,
<<"};\n">>,
<<"var links = v.values[0].metadata.Links;\n">>,
<<"for(var i in links) {\n">>,
<<"if (links[i][2] == \"editor\") {\n">>,
<<"summary.editor = links[i][1];\n">>,
<<"}\n">>,
<<"}\n">>,
<<"return [summary];\n">>,
<<"}">>])).
get_version_summaries(ArticleKey) ->
{ok, Client} = wriaki:riak_client(),
rhc:mapred(Client,
[{?B_HISTORY, ArticleKey}],
[{link, <<"archive">>, '_', false},
%{reduce, {jsanon, ?TIME_ORDER}, <<>>, false}, %TODO: paging
{map, {jsanon, ?SUMMARY_EXTRACTION}, <<>>, true}]).