source: mp3-find/trunk/bin/mp3db @ 1

Last change on this file since 1 was 1, checked in by peter, 18 years ago

Initial import

File size: 4.3 KB
Line 
1#!/usr/bin/perl -w
2use strict;
3
4use lib '/home/peter/projects/mp3-find/lib';
5use DBI;
6use MP3::Find;
7
8use File::Spec::Functions qw(catfile);
9use Getopt::Long;
10GetOptions(
11    'create' => \my $CREATE,
12    'file|f=s' => \my $DB_FILE,
13);
14
15$DB_FILE ||= catfile($ENV{HOME}, 'mp3.db');
16
17#TODO: hints on numeric columns
18my @COLUMNS = (
19    [ mtime => 'INTEGER' ],
20    [ FILENAME => 'TEXT' ], 
21    [ TITLE => 'TEXT' ], 
22    [ ARTIST => 'TEXT' ], 
23    [ ALBUM => 'TEXT' ],
24    [ YEAR => 'INTEGER' ], 
25    [ COMMENT => 'TEXT' ], 
26    [ GENRE => 'TEXT' ], 
27    [ TRACKNUM => 'INTEGER' ], 
28    [ VERSION => 'NUMERIC' ],
29    [ LAYER => 'INTEGER' ], 
30    [ STEREO => 'TEXT' ],
31    [ VBR => 'TEXT' ],
32    [ BITRATE => 'INTEGER' ], 
33    [ FREQUENCY => 'INTEGER' ], 
34    [ SIZE => 'INTEGER' ], 
35    [ OFFSET => 'INTEGER' ], 
36    [ SECS => 'INTEGER' ], 
37    [ MM => 'INTEGER' ],
38    [ SS => 'INTEGER' ],
39    [ MS => 'INTEGER' ], 
40    [ TIME => 'TEXT' ],
41    [ COPYRIGHT => 'TEXT' ], 
42    [ PADDING => 'INTEGER' ], 
43    [ MODE => 'INTEGER' ],
44    [ FRAMES => 'INTEGER' ], 
45    [ FRAME_LENGTH => 'INTEGER' ], 
46    [ VBR_SCALE => 'INTEGER' ],
47);
48
49my @DIRS = @ARGV;
50push @DIRS, $ENV{HOME} unless @DIRS;
51
52
53my $dbh = DBI->connect("dbi:SQLite:dbname=$DB_FILE",'','', { RaiseError => 1 });
54
55create_table($dbh) if $CREATE;
56read_mp3s(\@DIRS);
57
58sub read_mp3s {
59    my $dirs = shift;
60
61    my $mtime_sth = $dbh->prepare('SELECT mtime FROM mp3 WHERE FILENAME = ?');
62    my $insert_sth = $dbh->prepare(
63        'INSERT INTO mp3 (' . 
64            join(',', map { $$_[0] } @COLUMNS) .
65        ') VALUES (' .
66            join(',', map { '?' } @COLUMNS) .
67        ')'
68    );
69    my $update_sth = $dbh->prepare(
70        'UPDATE mp3 SET ' . 
71            join(',', map { "$$_[0] = ?" } @COLUMNS) . 
72        ' WHERE FILENAME = ?'
73    );
74   
75    for my $mp3 (find_mp3s(dir => $dirs, no_format => 1)) {
76        # see if the file has been modified since it was first put into the db
77        $mp3->{mtime} = (stat($mp3->{FILENAME}))[9];
78        $mtime_sth->execute($mp3->{FILENAME});
79        my $records = $mtime_sth->fetchall_arrayref;
80       
81        warn "Multiple records for $$mp3{FILENAME}\n" if @$records > 1;
82       
83        if (@$records == 0) {
84            $insert_sth->execute(map { $mp3->{$$_[0]} } @COLUMNS);
85            print "A $$mp3{FILENAME}\n";
86        } elsif ($mp3->{mtime} > $$records[0][0]) {
87            # the mp3 file is newer than its record
88            $update_sth->execute((map { $mp3->{$$_[0]} } @COLUMNS), $mp3->{FILENAME});
89            print "U $$mp3{FILENAME}\n";
90        }
91    }
92   
93    # as a workaround for the 'closing dbh with active staement handles warning
94    # (see http://rt.cpan.org/Ticket/Display.html?id=9643#txn-120724)
95    # NOT WORKING!!!
96    foreach ($mtime_sth, $insert_sth, $update_sth) {
97        $_->{Active} = 1;
98        $_->finish;
99    }
100}
101
102#TODO: hints on numeric vs. string columns, for proper sorting
103sub create_table {
104    my $dbh = shift;
105    $dbh->do('CREATE TABLE mp3 (' . join(',', map { "$$_[0] $$_[1]" } @COLUMNS) . ')');
106}
107
108=begin
109
110    CREATE TABLE mp3 (
111        mtime,
112       
113        FILENAME,
114       
115        TITLE,
116        ARTIST,
117        ALBUM,
118        YEAR,
119        COMMENT,
120        GENRE,
121        TRACKNUM,
122       
123        VERSION,         -- MPEG audio version (1, 2, 2.5)
124        LAYER,           -- MPEG layer description (1, 2, 3)
125        STEREO,          -- boolean for audio is in stereo
126   
127        VBR,             -- boolean for variable bitrate
128        BITRATE,         -- bitrate in kbps (average for VBR files)
129        FREQUENCY,       -- frequency in kHz
130        SIZE,            -- bytes in audio stream
131        OFFSET,          -- bytes offset that stream begins
132   
133        SECS,            -- total seconds
134        MM,              -- minutes
135        SS,              -- leftover seconds
136        MS,              -- leftover milliseconds
137        TIME,            -- time in MM:SS
138   
139        COPYRIGHT,       -- boolean for audio is copyrighted
140        PADDING,         -- boolean for MP3 frames are padded
141        MODE,            -- channel mode (0 = stereo, 1 = joint stereo,
142                         -- 2 = dual channel, 3 = single channel)
143        FRAMES,          -- approximate number of frames
144        FRAME_LENGTH,    -- approximate length of a frame
145        VBR_SCALE        -- VBR scale from VBR header
146    );
147
148=cut
Note: See TracBrowser for help on using the repository browser.