-
-
Notifications
You must be signed in to change notification settings - Fork 160
/
Copy pathtimestamps.rb
149 lines (130 loc) · 4.33 KB
/
timestamps.rb
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true
require "set"
module ROM
module Plugins
module Command
# A plugin for automatically adding timestamp values
# when executing a command
#
# Set up attributes to timestamp when the command is called
#
# @example
# class CreateTask < ROM::Commands::Create[:sql]
# result :one
# use :timestamps, timestamps: %i(created_at, updated_at), datestamps: %i(:written)
# end
#
# create_user = rom.command(:user).create.curry(name: 'Jane')
#
# result = create_user.call
# result[:created_at] #=> Time.now.utc
#
# @api public
class Timestamps < Module
attr_reader :timestamps, :datestamps
def initialize(timestamps: [], datestamps: [])
@timestamps = store_attributes(timestamps)
@datestamps = store_attributes(datestamps)
end
# @api private
def store_attributes(attr)
attr.is_a?(Array) ? attr : Array[attr]
end
# @api private
def included(klass)
initialize_timestamp_attributes(klass)
klass.include(InstanceMethods)
klass.extend(ClassInterface)
super
end
def initialize_timestamp_attributes(klass)
klass.setting :timestamp_columns, default: Set.new, reader: true
klass.setting :datestamp_columns, default: Set.new, reader: true
klass.before :set_timestamps
klass.config.timestamp_columns = klass.timestamp_columns.merge(timestamps) if timestamps.any?
klass.config.datestamp_columns = klass.datestamp_columns.merge(datestamps) if datestamps.any?
end
module InstanceMethods
# @api private
def timestamp_columns
self.class.timestamp_columns
end
# @api private
def datestamp_columns
self.class.datestamp_columns
end
# Set the timestamp attributes on the given tuples
#
# @param [Array<Hash>, Hash] tuples the input tuple(s)
#
# @return [Array<Hash>, Hash]
#
# @api private
def set_timestamps(tuples, *)
timestamps = build_timestamps
map_input_tuples(tuples) { |t| timestamps.merge(t) }
end
private
# @api private
def build_timestamps
time = Time.now.utc
date = Date.today
timestamps = {}
timestamp_columns.each do |column|
timestamps[column.to_sym] = time
end
datestamp_columns.each do |column|
timestamps[column.to_sym] = date
end
timestamps
end
end
module ClassInterface
# @api private
# Set up attributes to timestamp when the command is called
#
# @example
# class CreateTask < ROM::Commands::Create[:sql]
# result :one
# use :timestamps
# timestamps :created_at, :updated_at
# end
#
# create_user = rom.command(:user).create.curry(name: 'Jane')
#
# result = create_user.call
# result[:created_at] #=> Time.now.utc
#
# @param [Array<Symbol>] names A list of attribute names
#
# @api public
def timestamps(*names)
config.timestamp_columns = timestamp_columns.merge(names)
end
alias_method :timestamp, :timestamps
# Set up attributes to datestamp when the command is called
#
# @example
# class CreateTask < ROM::Commands::Create[:sql]
# result :one
# use :timestamps
# datestamps :created_on, :updated_on
# end
#
# create_user = rom.command(:user).create.curry(name: 'Jane')
#
# result = create_user.call
# result[:created_at] #=> Date.today
#
# @param [Array<Symbol>] names A list of attribute names
#
# @api public
def datestamps(*names)
config.datestamp_columns = datestamp_columns.merge(names)
end
alias_method :datestamp, :datestamps
end
end
end
end
end