27#define __DCL_TRACE1_N __DCL_TRACE1
28#define __DCL_TRACE2_N __DCL_TRACE2
29#define __DCL_TRACE3_N __DCL_TRACE3
31#define __DCL_TRACE1_N(fmt, arg)
32#define __DCL_TRACE2_N(fmt, arg1, arg2)
33#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
38#if __DCL_HAVE_THIS_FILE__
58 size_t first =
__args.database().search(L
"DRIVER *=",
true);
59 if (first != (
size_t)-1) {
60 String driver =
__args.database().substring(L
"DRIVER *= *[^;]+",
true);
61 if (driver.isEmpty()) {
62 driver =
__args.database().substring(first);
64 if (!driver.isEmpty()) {
65 if (driver.indexOf(L
'{') != (
size_t)-1) {
69 driver = driver.substring(driver.indexOf(L
'=') + 1).trim();
72 if (!driver.isEmpty()) {
75 __args.output() << L
"Database connected. ["
90#if defined(__DCL_DEBUG) && __TRACE_THIS
92 File::off_t _n = file.
size();
108 size_t n = file.
read(buf, 32);
110 if (memcmp(buf,
"ID3", 3) == 0) {
112 if (_info.
id3v2.read(file, buf)) {
113 id3v2Version = id3v2.version();
116 else if (memcmp(buf,
"APETAGEX", 8) == 0) {
118 if (apev2.read(file, buf, 0)) {
119 apeVersion = apev2.version() / 1000;
126 n = file.
read(buf, 160);
129 n, String::tryString(buf, 160).data());
130 if (apeVersion == 0) {
131 if (memcmp(buf,
"APETAGEX", 8) == 0) {
133 if (apev2.read(file, buf, -160)) {
134 apeVersion = apev2.version() / 1000;
137 else if (memcmp(&buf[128],
"APETAGEX", 8) == 0) {
139 if (apev2.read(file, buf, -32)) {
140 apeVersion = apev2.version() / 1000;
145 if (memcmp(&buf[32],
"TAG", 3) == 0) {
146 if (id3v1.read(&buf[32])) {
147 id3v1Version = id3v1.version();
156 String path = _dirname + _filename;
159 time_t atime, mtime, ctime;
167 if (_filename.toLowerCase().endsWith(L
".mp3")) {
215 while (dir.read(entry)) {
217 String name = entry.name();
219 if (name.compare(L
"..", name.length()) != 0) {
220 readDir(dir.path() + entry.name());
224 read(dir.path(), name);
241 out.printf(L
" tags[%03d]",
242 id3v2.version() * 100 + apev2.version() / 100 + id3v1.version());
243 out << L
" size[" << _info.
size << L
"]"
245 << L
" notes[" << _info.
notes << L
"]"
248 out << L
" format[" << _info.
format << L
"]"
249 << L
" width[" << _info.
width << L
"]"
250 << L
" height[" << _info.
height << L
"]"
251 << L
" duration[" << _info.
duration << L
"]"
254 if (!
args().verbose()) {
258 if (id3v2.version() > 0) {
260 out << id3v2.toString() <<
endl;
262 for (
size_t i = 0; i < id3v2.frames().size(); i++) {
268 if (apev2.version() > 0) {
270 out << apev2.toString() <<
endl;
272 for (
size_t i = 0; i < apev2.items().size(); i++) {
274 out << item.toString() <<
endl;
278 if (id3v1.version() > 0) {
280 out << id3v1.toString() <<
endl;
294 "SELECT COALESCE(MAX(DIR_ID), 1000) FROM STOR_DIR"
304 "SELECT COALESCE(MAX(FILE_ID), 10000) FROM STOR_FILE"
318 "INSERT INTO STOR_DIR ("
319 "DIR_ID, PATH, CREA_TS, MODI_TS"
322 ":DIR_ID, :PATH, :CREA_TS, :MODI_TS"
328 q.
params()[2].setValue(now);
329 q.
params()[3].setValue(now);
332 out << L
" INSERT STOR_DIR [" <<
__dirId << L
"]["
338 "INSERT INTO STOR_FILE ("
339 "FILE_ID, NAME, USER_ID, STOR_ID, TYPE_ID"
340 ", DIR_ID, FILE_NM, FILE_SZ, FILE_AT, FILE_MT, FILE_CT, FILE_ER"
341 ", MEDI_FM, MEDI_WI, MEDI_HE, MEDI_DU, MEDI_NF"
342 ", READ_CO, CREA_TS, MODI_TS"
345 ":FILE_ID, :NAME, 0, 0, 0"
346 ", :DIR_ID, :FILE_NM, :FILE_SZ, :FILE_AT, :FILE_MT, :FILE_CT, :FILE_ER"
347 ", :MEDI_FM, :MEDI_WI, :MEDI_HE, :MEDI_DU, :MEDI_NF"
348 ", 0, :CREA_TS, :MODI_TS"
370 out << L
" INSERT STOR_FILE [" <<
__fileId << L
"]["
373 if (_info.
id3v1.version() > 0) {
374 if (_info.
id3v1.title().length() > 0) {
376 "INSERT INTO ID3V1 ("
377 "FILE_ID, TITLE, ARTIST, ALBUM, YEAR_"
378 ", COMMENT_, TRACK, GENRE"
381 ":FILE_ID, :TITLE, :ARTIST, :ALBUM, :YEAR_"
382 ", :COMMENT_, :TRACK, :GENRE"
389 if (_info.
id3v1.artist().isEmpty())
394 if (_info.
id3v1.album().isEmpty())
399 if (_info.
id3v1.year().isEmpty())
404 if (_info.
id3v1.comment().isEmpty())
414 out << L
" INSERT ID3V1" <<
endl;
418 args().errout() << L
"Title is NULL "
419 << _info.
id3v1.toString()
424 if (_info.
id3v2.version() > 0) {
426 "INSERT INTO ID3V2 ("
427 "FILE_ID, VERSION, FLAGS, SIZE_, FSBITS"
430 ":FILE_ID, :VERSION, :FLAGS, :SIZE_, :FSBITS"
442 "INSERT INTO ID3V2_FRAME ("
443 "FILE_ID, NO_, FRAME_ID, SIZE_, FLAGS"
444 ", ENCODING, TYPE_, URL, DESCRIPTION, TEXT_, BINARY_"
447 ":FILE_ID, :NO_, :FRAME_ID, :SIZE_, :FLAGS"
448 ", :ENCODING, :TYPE_, :URL, :DESCRIPTION, :TEXT_, :BINARY_"
451 for (
size_t i = 0; i < _info.
id3v2.frames().size(); i++) {
461 if (frame.
url().isEmpty())
471 if (frame.
text().isEmpty())
476 if (frame.
binary().length() == 0 || 100 < frame.
binary().length())
486 out << L
" INSERT ID3V2 ID3V2_FRAME["
487 << _info.
id3v2.frames().size() << L
"]" <<
endl;
491 if (_info.
apev2.version() > 0) {
494 "FILE_ID, VERSION, SIZE_, COUNT_, FLAGS"
497 ":FILE_ID, :VERSION, :SIZE_, :COUNT_, :FLAGS"
509 "INSERT INTO APE_ITEM ("
510 "FILE_ID, NO_, SIZE_, FLAGS"
514 ":FILE_ID, :NO_, :SIZE_, :FLAGS"
518 for (
size_t i = 0; i < _info.
apev2.items().size(); i++) {
523 q.
params().
byName(L
"FLAGS").setValue((int32_t)item.flags());
526 if (item.value().isEmpty())
535 out << L
" INSERT APE APE_ITEM["
536 << _info.
apev2.items().size() << L
"]" <<
endl;
#define __DCL_THROWS2(e1, e2)
#define __DCL_TRACE2_N(fmt, arg1, arg2)
#define __DCL_TRACE2(fmt, arg1, arg2)
DCLCVAR const struct __endl endl
void assign(time_t _timer)
static DateTime getCurrentLocalTime()
virtual String toString() const
String toStringAll() const
off_t seek(off_t _offset, int _whence) __DCL_THROWS1(IOException *)
virtual size_t read(void *_buf, size_t _n) __DCL_THROWS1(IOException *)
const String & path() const
off_t size() const __DCL_THROWS1(IOException *)
static bool time(const String &_path, time_t *_atime, time_t *_mtime, time_t *_ctime)
static uint64_t size(const String &_path) __DCL_THROWS1(IOException *)
const String & url() const
const String & description() const
const String & text() const
const ByteString & binary() const
virtual String toString() const
SQLParam & byName(const wchar_t *_name) _CONST __DCL_THROWS1(InvalidIndexException *)
void prepare(const String &_sql) __DCL_THROWS1(SQLException *)
_CONST SQLParams & params() _CONST
_CONST SQLFields & fields() _CONST
void execute() __DCL_THROWS1(SQLException *)
void fetch() __DCL_THROWS1(SQLException *)
TagReader(const MainArguments &_args) __DCL_THROWS2(SQLDriverException *
SQLException *void readTag(const String &_path, FileInfo &_info)
void persist(const FileInfo &_info)
const MainArguments & args() const
void read(const String &_dirname, const String &_filename)
void print(const FileInfo &_info) const
const MainArguments & __args
void readDir(const String &_path)