source: bookmarks/trunk/Bookmarks.pm @ 2

Last change on this file since 2 was 2, checked in by peter, 12 years ago

Added exisiting bookmarks project files

File size: 5.6 KB
Line 
1package Bookmarks;
2
3use Class::Accessor 'antlers';
4use Bookmark;
5
6has dbh => ( is => 'ro');
7
8sub get_bookmark {
9    my $self = shift;
10    my $params = shift;
11    my $sth;
12    if ($params->{id}) {
13        $sth = $self->dbh->prepare('select id,resources.uri,title,ctime,mtime from bookmarks join resources on bookmarks.uri=resources.uri where id=?');
14        $sth->execute($params->{id});
15    } elsif ($params->{uri}) {
16        $sth = $self->dbh->prepare('select id,resources.uri,title,ctime,mtime from bookmarks join resources on bookmarks.uri=resources.uri where resources.uri=?');
17        $sth->execute($params->{uri});
18    } else {
19        die "Must specify either id or uri";
20    }
21    my $bookmark = $sth->fetchrow_hashref;
22    if ($bookmark) {
23        my $sth_tag = $self->dbh->prepare('select tag from tags where uri = ? order by tag');
24        $sth_tag->execute($bookmark->{uri});
25        $bookmark->{tags} = [ map { $$_[0] } @{ $sth_tag->fetchall_arrayref } ];
26    }
27    return $bookmark;
28}
29
30sub get_resources {
31    my $self = shift;
32    my $params = shift;
33    my $tag = $params->{tag};
34    my $sth_resource;
35    if ($tag) {
36        $sth_resource = $self->dbh->prepare('select * from resources join tags on resources.uri = tags.uri join bookmarks on resources.uri = bookmarks.uri where tags.tag = ? order by ctime desc');
37        $sth_resource->execute($tag);
38    } else {
39        $sth_resource = $self->dbh->prepare('select * from resources join bookmarks on resources.uri = bookmarks.uri order by ctime desc');
40        $sth_resource->execute;
41    }
42
43    my $sth_tag = $self->dbh->prepare('select tag from tags where uri = ? order by tag');
44    my @resources;
45    while (my $resource = $sth_resource->fetchrow_hashref) {
46        $sth_tag->execute($resource->{uri});
47        $resource->{tags} = [ map { $$_[0] } @{ $sth_tag->fetchall_arrayref } ];
48        push @resources, $resource;
49    }
50    return @resources;
51}
52
53sub get_tags {
54    my $self = shift;
55    my $params = shift;
56    my $tag = $params->{selected};
57    my $sth_all_tags = $self->dbh->prepare('select tag, count(tag) as count, tag = ? as selected from tags group by tag order by tag');
58    $sth_all_tags->execute($tag);
59    my $all_tags = $sth_all_tags->fetchall_arrayref({});
60    return @{ $all_tags };
61}
62
63sub get_cotags {
64    my $self = shift;
65    my $params = shift;
66    my $tag = $params->{tag};
67    my $sth = $self->dbh->prepare('select tag, count(tag) as count from tags where tag != ? and uri in (select uri from tags where tag = ?) group by tag order by tag');
68    $sth->execute($tag, $tag);
69    return @{ $sth->fetchall_arrayref({}) };
70}
71
72sub add {
73    my $self = shift;
74    my $bookmark = shift;
75
76    my $uri = $bookmark->{uri};
77    my $title = $bookmark->{title};
78    #TODO: accept a ctime or mtime
79    my $mtime = my $ctime = $bookmark->{ctime} || time;
80
81    # create an entry for the resource
82    my $sth_resource = $self->dbh->prepare('insert into resources (uri, title) values (?, ?)');
83    eval {
84        $sth_resource->execute($uri, $title);
85    };
86    if ($@) {
87        if ($@ =~ /column uri is not unique/) {
88            # this is not truly an error condition; the resource is already listed
89            # update the title instead
90            my $sth_update = $self->dbh->prepare('update resources set title = ? where uri = ?');
91            $sth_update->execute($title, $uri);
92        } else {
93            die $@;
94        }
95    }
96
97    # create the bookmark
98    my $sth_bookmark = $self->dbh->prepare('insert into bookmarks (uri, ctime, mtime) values (?, ?, ?)');
99    eval {
100        $sth_bookmark->execute($uri, $ctime, $mtime);
101    };
102    if ($@) {
103        if ($@ =~ /column uri is not unique/) {
104            # this is not truly an error condition; the bookmark was already there
105            # update the mtime instead
106            # TODO: only update mtime if the tag list is changed?
107            my $sth_update = $self->dbh->prepare('update bookmarks set mtime = ? where uri = ?');
108            $sth_update->execute($mtime, $uri);
109        } else {
110            die $@;
111        }
112    }
113
114    my %new_tags = map { $_ => 1 } @{ $bookmark->{tags} };
115    my $sth_delete_tag = $self->dbh->prepare('delete from tags where uri = ? and tag = ?');
116    my $sth_insert_tag = $self->dbh->prepare('insert into tags (uri, tag) values (?, ?)');
117    my $sth_current_tags = $self->dbh->prepare('select tag from tags where uri = ?');
118    $sth_current_tags->execute($uri);
119    while (my ($tag) = $sth_current_tags->fetchrow_array) {
120        if (!$new_tags{$tag}) {
121            # if a current tag is not in the new tags, remove it from the database
122            $sth_delete_tag->execute($uri, $tag);
123        } else {
124            # if a new tag is already in the database, remove it from the list of tags to add
125            delete $new_tags{$tag};
126        }
127    }
128    for my $tag (keys %new_tags) {
129        $sth_insert_tag->execute($uri, $tag);
130    }
131
132=begin
133
134    # clear all tags
135    my $sth_delete_tag = $self->dbh->prepare('delete from tags where uri = ?');
136    $sth_delete_tag->execute($uri);
137    my $sth_tag = $self->dbh->prepare('insert into tags (uri, tag) values (?, ?)');
138    for my $tag (@{ $bookmark->{tags} }) {
139        #print $tag, "\n";
140        # prevent duplicate (uri,tag) pairs in the database
141        # TODO: should POST with a set of tags ever remove tags?
142        eval {
143            $sth_tag->execute($uri, $tag);
144        };
145        if ($@) {
146            if ($@ =~ /columns uri, tag are not unique/) {
147                # this is not truly an error condition; the tag was already there
148            } else {
149                die $@;
150            }
151        }
152    }
153
154=cut
155
156    # return the newly created or updated bookmark
157    return $self->get_bookmark({ uri => $uri });
158}
159
160# module returns true
1611;
Note: See TracBrowser for help on using the repository browser.