File Coverage

blib/lib/Synth/Config.pm
Criterion Covered Total %
statement 86 93 92.4
branch 13 24 54.1
condition n/a
subroutine 16 17 94.1
pod 9 10 90.0
total 124 144 86.1


line stmt bran cond sub pod time code
1             package Synth::Config;
2             our $AUTHORITY = 'cpan:GENE';
3              
4             # ABSTRACT: Synthesizer settings librarian
5              
6             our $VERSION = '0.0038';
7              
8 1     1   1264 use Moo;
  1         11667  
  1         5  
9 1     1   2053 use strictures 2;
  1         1689  
  1         53  
10 1     1   190 use Carp qw(croak);
  1         2  
  1         43  
11 1     1   495 use Mojo::JSON qw(from_json to_json);
  1         212427  
  1         70  
12 1     1   556 use Mojo::SQLite ();
  1         235529  
  1         44  
13 1     1   573 use namespace::clean;
  1         11990  
  1         6  
14              
15              
16             has model => (
17             is => 'rw',
18             );
19              
20              
21             has dbname => (
22             is => 'ro',
23             required => 1,
24             default => sub { 'synth-config.db' },
25             );
26              
27             has _sqlite => (is => 'lazy');
28              
29             sub _build__sqlite {
30 1     1   24 my ($self) = @_;
31 1         13 my $sqlite = Mojo::SQLite->new('sqlite:' . $self->dbname);
32 1         3002 return $sqlite->db;
33             }
34              
35              
36             has verbose => (
37             is => 'ro',
38             isa => sub { croak "$_[0] is not a boolean" unless $_[0] =~ /^[01]$/ },
39             default => sub { 0 },
40             );
41              
42              
43             sub BUILD {
44 1     1 0 13 my ($self, $args) = @_;
45 1 50       6 return unless $args->{model};
46             # sanitize the model name
47 1         7 (my $model = $args->{model}) =~ s/\W/_/g;
48 1         9 $self->model(lc $model);
49             # create the model table unless it's already there
50 1         18 $self->_sqlite->query(
51             'create table if not exists '
52             . $self->model
53             . ' (
54             id integer primary key autoincrement,
55             settings json not null,
56             name text not null
57             )'
58             );
59             }
60              
61              
62             sub make_setting {
63 3     3 1 33138 my ($self, %args) = @_;
64 3         12 my $id = delete $args{id};
65 3         7 my $name = delete $args{name};
66 3 50       41 croak 'No columns given' unless keys %args;
67 3 100       12 if ($id) {
68             my $result = $self->_sqlite->select(
69             $self->model,
70             ['settings'],
71             { id => $id },
72 1         29 )->expand(json => 'settings')->hash->{settings};
73 1         1889 for my $arg (keys %args) {
74 1 50       32 $args{$arg} = '' unless defined $args{$arg};
75             }
76 1         13 my $params = { %$result, %args };
77 1         31 $self->_sqlite->update(
78             $self->model,
79             { settings => to_json($params) },
80             { id => $id },
81             );
82             }
83             else {
84 2         81 $id = $self->_sqlite->insert(
85             $self->model,
86             {
87             name => $name,
88             settings => to_json(\%args),
89             },
90             )->last_insert_id;
91             }
92 3         8989 return $id;
93             }
94              
95              
96             sub recall_setting {
97 3     3 1 1819 my ($self, %args) = @_;
98 3         7 my $id = delete $args{id};
99 3 50       11 croak 'No id given' unless $id;
100 3         78 my $result = $self->_sqlite->select(
101             $self->model,
102             ['name', 'settings'],
103             { id => $id },
104             )->expand(json => 'settings')->hash;
105 3         5800 my $setting = $result->{settings};
106 3         78 $setting->{name} = $result->{name};
107 3         20 return $setting;
108             }
109              
110              
111             sub search_settings {
112 5     5 1 5734 my ($self, %args) = @_;
113 5         14 my $name = delete $args{name};
114 5         8 my @where;
115 5 100       19 push @where, "name = '$name'" if $name;
116 5         15 for my $arg (keys %args) {
117 2 50       9 next unless $args{$arg};
118 2         44 $args{$arg} =~ s/'/''/g; # escape the single-quote
119 2         11 push @where, q/json_extract(settings, '$./ . $arg . q/') = / . "'$args{$arg}'";
120             }
121 5 50       12 return [] unless @where;
122 5         29 my $sql = q/select id,name,settings,json_extract(settings, '$.group') as mygroup, json_extract(settings, '$.parameter') as parameter from /
123             . $self->model
124             . ' where ' . join(' and ', @where)
125             . ' order by name,mygroup,parameter';
126 5 50       139 print "Search SQL: $sql\n" if $self->verbose;
127 5         172 my $results = $self->_sqlite->query($sql);
128 5         1251 my @settings;
129 5         23 while (my $next = $results->hash) {
130 5         281 push @settings, { $next->{id} => from_json($next->{settings}) };
131             # add the setting name to the settings data so we can use it in the templates
132 5         1386 $settings[-1]->{ $next->{id} }{name} = $next->{name};
133             }
134 5         138 return \@settings;
135             }
136              
137              
138             sub recall_all {
139 2     2 1 1140 my ($self) = @_;
140 2         13 my $sql = q/select id,name,settings,json_extract(settings, '$.group') as mygroup from /
141             . $self->model
142             . ' order by name,mygroup';
143 2         72 my $results = $self->_sqlite->query($sql);
144 1         255 my @settings;
145 1         6 while (my $next = $results->hash) {
146 2         96 push @settings, { $next->{id} => from_json($next->{settings}) };
147             # add the setting name to the settings data
148 2         550 $settings[-1]->{ $next->{id} }{name} = $next->{name};
149             }
150 1         32 return \@settings;
151             }
152              
153              
154             sub recall_models {
155 0     0 1 0 my ($self) = @_;
156 0         0 my @models;
157 0         0 my $results = $self->_sqlite->query(
158             "select name from sqlite_schema where type='table' order by name"
159             );
160 0         0 while (my $next = $results->array) {
161 0 0       0 next if $next->[0] =~ /^sqlite/;
162 0         0 push @models, $next->[0];
163             }
164 0         0 return \@models;
165             }
166              
167              
168             sub recall_names {
169 1     1 1 964 my ($self) = @_;
170 1         3 my @names;
171 1         30 my $results = $self->_sqlite->query(
172             'select distinct name from ' . $self->model
173             );
174 1         380 while (my $next = $results->array) {
175 1         56 push @names, $next->[0];
176             }
177 1         20 return \@names;
178             }
179              
180              
181             sub remove_setting {
182 1     1 1 1322 my ($self, %args) = @_;
183 1         4 my $id = delete $args{id};
184 1 50       5 croak 'No id given' unless $id;
185 1         27 $self->_sqlite->delete(
186             $self->model,
187             { id => $id }
188             );
189             }
190              
191              
192             sub remove_settings {
193 1     1 1 970 my ($self, %args) = @_;
194 1         4 my $name = delete $args{name};
195 1 50       4 croak 'No name given' unless $name;
196 1         26 $self->_sqlite->delete(
197             $self->model,
198             { name => $name }
199             );
200             }
201              
202              
203             sub remove_model {
204 1     1 1 2651 my ($self) = @_;
205 1         27 $self->_sqlite->query(
206             'drop table ' . $self->model
207             );
208             }
209              
210             1;
211              
212             __END__