forked from nestorInc/jukebox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdb.rb
More file actions
259 lines (229 loc) · 7.04 KB
/
db.rb
File metadata and controls
259 lines (229 loc) · 7.04 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#!/usr/bin/env ruby
require 'sqlite3'
require 'display.rb'
class Song
attr_accessor :mid
attr_accessor :src
attr_accessor :dst
attr_accessor :title
attr_accessor :artist
attr_accessor :album
attr_accessor :years
attr_accessor :status
attr_accessor :bitrate
attr_accessor :frames
attr_accessor :duration
def initialize(params = {})
@mid = params["mid"];
@src = params["src"] && params["src"].encode(Encoding.locale_charmap);
@dst = params["dst"] && params["dst"].encode(Encoding.locale_charmap);
@title = params["title"];
@artist = params["artist"];
@album = params["album"];
@years = params["years"];
@status = params["status"] && params["status"].to_i;
@duration = params["duration"] && params["duration"].to_i;
@bitrate = params["bitrate"] && params["bitrate"].to_i;
@frames = params["frames"];
if(@frames == nil)
@frames = [];
else
@frames = @frames.split(",").map { |v| v.to_i(); }
end
end
def to_client()
res = {}
res[:mid ] = @mid if(@mid);
res[:title ] = @title if(@title);
res[:artist ] = @artist if(@artist);
res[:album ] = @album if(@album);
res[:duration] = @duration if(@duration);
res;
end
def to_db()
res = {}
res[:mid ] = @mid if(@mid);
res[:src ] = @src if(@src);
res[:dst ] = @dst if(@dst);
res[:title ] = @title if(@title);
res[:artist ] = @artist if(@artist);
res[:album ] = @album if(@album);
res[:years ] = @years if(@years);
res[:status ] = @status if(@status);
res[:bitrate ] = @bitrate if(@bitrate);
res[:duration] = @duration if(@duration);
res[:frames ] = @frames .map { |v| v.to_s(); }.join(",") if(@frames);
res;
end
def self.from_db()
Proc.new { |row|
next if(row == nil);
self.new(row);
}
end
def to_s()
str = "#{@title} - #{@artist} - #{@album}"
end
end
class Library
FILE_WAIT = 1;
FILE_BAD_TAG = 2;
FILE_ENCODING_PROGRESS = 3;
FILE_ENCODING_FAIL = 4;
FILE_OK = 5;
def initialize()
@db = SQLite3::Database.new("jukebox.db")
@db.results_as_hash = true
@db.execute( "create table if not exists library (
mid INTEGER PRIMARY KEY,
src TEXT, dst TEXT,
title TEXT, artist TEXT, album TEXT, years INTEGER UNSIGNED NULL,
status INTEGER, frames TEXT, bitrate INTEGER, duration INTEGER);" );
req = @db.prepare("UPDATE library SET status=#{FILE_WAIT} WHERE status=#{FILE_ENCODING_PROGRESS}");
res = req.execute!();
req.close();
res;
log("library initialized.");
end
# searching methods here
#SELECT * FROM music ORDER BY mid LIMIT 60,10;
def get_nb_songs()
req = @db.prepare("SELECT COUNT (*) FROM library WHERE status=#{FILE_OK}");
res = req.execute!();
req.close();
res[0].at(0);
end
def get_total(field, comparison, value)
if(field)
if( "like" == comparison)
req = @db.prepare("SELECT COUNT (*) FROM library WHERE status=#{FILE_OK} AND #{field} LIKE \"%\" || :name || \"%\"");
else
req = @db.prepare("SELECT COUNT (*) FROM library WHERE status=#{FILE_OK} AND #{field} LIKE :name");
end
else
req=@db.prepare("SELECT COUNT (*) FROM library WHERE status=#{FILE_OK}");
end
res = req.execute!(:name => value);
req.close();
res[0].at(0);
end
def get_file(*mids)
if(mids.size == 0 || mids[0] == nil)
req = @db.prepare("SELECT * FROM library WHERE status=#{FILE_OK} ORDER BY RANDOM() LIMIT 1");
res = req.execute().map(&Song.from_db);
req.close();
else
req = @db.prepare("SELECT * FROM library WHERE mid=? AND status=#{FILE_OK} LIMIT 1");
res = mids.map { |mid|
req.execute(mid).map(&Song.from_db).first;
}
req.close();
end
res;
end
def get_random_from_artist(artist)
if(artist != nil)
req = @db.prepare("SELECT * FROM library WHERE artist LIKE \"%#{artist}%\" AND status=#{FILE_OK} ORDER BY RANDOM() LIMIT 1");
res = req.execute();
req.close();
end
res.map(&Song.from_db).first
end
# search value
# search field
# order by order by way
# first result result count
def secure_request(fieldsSelection, value, comparison, field, orderBy, orderByWay, firstResult, resultCount)
field = "artist" if(field != "title" && field != "album");
orderBy = "artist, album, title" if(orderBy != "title" && orderBy != "album");
if(orderByWay == "down")
orderByWay = "DESC";
else
orderByWay = "ASC";
end
if( nil != firstResult && nil != resultCount)
firstResult = 0 if(!(firstResult.is_a? Integer))
firstResult = 0 if(firstResult < 0)
end
if("like" == comparison)
value = '%' + value + '%';
end
return request(fieldsSelection, value, field, orderBy, orderByWay, firstResult, resultCount);
end
def request(fieldsSelection, value, field, orderBy, orderByWay, firstResult, resultCount)
if( fieldsSelection )
request = "SELECT " + fieldsSelection + " FROM library WHERE status=#{FILE_OK} ";
else
request = "SELECT * FROM library WHERE status=#{FILE_OK} ";
end
request << "AND #{field} LIKE :name " if(field != nil);
if(orderBy != nil)
request << "ORDER BY #{orderBy} ";
request << "#{orderByWay} " if(orderByWay != nil);
end
if(firstResult && resultCount)
request << "LIMIT #{firstResult},#{resultCount}";
else
if(resultCount)
request << "LIMIT #{resultCount}";
end
end
warning("Querying database : #{request}");
req = @db.prepare(request);
res = req.execute(:name => value).map(&Song.from_db);
req.close();
return res;
end
def encode_file()
begin
req = @db.prepare("SELECT * FROM library WHERE status=#{FILE_WAIT} LIMIT 1");
res = req.execute().map(&Song.from_db);
req.close();
return nil if(res[0] == nil)
res = res.first;
rescue => e
error(e.to_s + res.to_s, true, $error_file);
change_stat(res[0], FILE_ENCODING_FAIL);
res = encode_file();
end
res;
end
def change_stat(mid, state)
req = @db.prepare("UPDATE library SET status=? WHERE mid=?");
res = req.execute!(state, mid);
req.close();
res;
end
def check_file(src)
req = @db.prepare("SELECT mid FROM library WHERE src=?");
res = req.execute!(src);
req.close();
res.size == 0;
end
def add(song)
req = "INSERT INTO library (";
v = song.to_db();
req << v.map { |k, v|
k
}.join(", ");
req << ") VALUES(";
req << v.map { |k, v|
":#{k}";
}.join(", ");
req << ");";
st = @db.prepare(req);
st.execute(v);
st.close();
end
def update(song)
req = "UPDATE library SET ";
v = song.to_db();
req << v.map { |k, v|
"#{k}=:#{k}";
}.join(", ")
req << " WHERE mid=:mid";
st = @db.prepare(req);
st.execute(v);
st.close();
end
end