fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2010-11-10 10:11 am

[dw-free] Implement v-gifts

[commit: http://hg.dwscoalition.org/dw-free/rev/766a365f5fd2]

http://bugs.dwscoalition.org/show_bug.cgi?id=215

Keep track of how many vgifts have been sold.

Patch by [personal profile] kareila.

Files modified:
  • bin/upgrading/update-db-general.pl
  • cgi-bin/DW/VirtualGift.pm
--------------------------------------------------------------------------------
diff -r abcdbb56342b -r 766a365f5fd2 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl	Wed Nov 10 18:01:41 2010 +0800
+++ b/bin/upgrading/update-db-general.pl	Wed Nov 10 18:11:27 2010 +0800
@@ -36,6 +36,15 @@ CREATE TABLE vgift_ids (
     mime_large   VARCHAR(255),
 
     UNIQUE KEY (name)
+)
+EOC
+
+register_tablecreate("vgift_counts", <<'EOC');
+CREATE TABLE vgift_counts (
+    vgiftid    INT UNSIGNED NOT NULL,
+    count      INT UNSIGNED NOT NULL DEFAULT 0,
+
+    PRIMARY KEY (vgiftid)
 )
 EOC
 
@@ -3933,6 +3942,11 @@ EOF
         set_dbnote( "sitekeywords_binary", 1 )
     }
 
+    if ( table_relevant( "vgift_counts" ) && ! check_dbnote("init_vgift_counts") ) {
+        do_sql( "INSERT IGNORE INTO vgift_counts (vgiftid) SELECT vgiftid FROM vgift_ids" );
+        set_dbnote( "init_vgift_counts", 1 );
+    }
+
 });
 
 
diff -r abcdbb56342b -r 766a365f5fd2 cgi-bin/DW/VirtualGift.pm
--- a/cgi-bin/DW/VirtualGift.pm	Wed Nov 10 18:01:41 2010 +0800
+++ b/cgi-bin/DW/VirtualGift.pm	Wed Nov 10 18:11:27 2010 +0800
@@ -137,6 +137,11 @@ sub create {
     my $props = join( ', ', keys %vg );
     my $qs = join( ', ', map { '?' } keys %vg );
     $dbh->do( "INSERT INTO vgift_ids ($props) VALUES ($qs)", undef, values %vg );
+    die $dbh->errstr if $dbh->err;
+
+    # initialize this gift in the vgift_counts table
+    $dbh->do( "INSERT INTO vgift_counts (vgiftid,count) VALUES (?,0)",
+              undef, $self->id );
     die $dbh->errstr if $dbh->err;
 
     $self->_expire_aggregate_keys;
@@ -236,6 +241,19 @@ sub edit {
 
 sub mark_active   { $_[0]->edit( active => 'Y' ) }
 sub mark_inactive { $_[0]->edit( active => 'N' ) }
+
+sub mark_sold {
+    my ( $self ) = @_;
+    return undef unless $self->id;
+
+    my $dbh = LJ::get_db_writer();
+    $dbh->do( "UPDATE vgift_counts SET count=count+1 WHERE vgiftid=?",
+              undef, $self->id );
+    die $dbh->errstr if $dbh->err;
+
+    LJ::MemCache::delete( $self->num_sold_memkey );
+    return $self;
+}
 
 sub tags {
     # taglist is a comma separated string of tagnames.
@@ -439,14 +457,19 @@ sub delete {
         LJ::mogclient()->delete( $self->img_mogkey( 'small' ) );
     }
 
-    # wipe the relevant rows and memkeys
+    # wipe the relevant rows from the database
     $self->_tagwipe;
+    my $dbh = LJ::get_db_writer();
+    $dbh->do( "DELETE FROM vgift_ids WHERE vgiftid=$id" );
+    die $dbh->errstr if $dbh->err;
+    $dbh->do( "DELETE FROM vgift_counts WHERE vgiftid=$id" );
+    die $dbh->errstr if $dbh->err;
+
+    # wipe the relevant keys from memcache
+    LJ::MemCache::delete( $self->num_sold_memkey );
     $self->_expire_relevant_keys;
     $self->_remove_from_memcache;  # LJ::MemCacheable
 
-    my $dbh = LJ::get_db_writer();
-    $dbh->do( "DELETE FROM vgift_ids WHERE vgiftid=$id" );
-    die $dbh->errstr if $dbh->err;
     return 1;
 }
 
@@ -601,7 +624,8 @@ sub can_be_deleted_by {
 sub can_be_deleted_by {
     my $self = shift;
 
-    # FIXME: if the vgift has been purchased, don't allow
+    # if the vgift has been purchased, don't allow
+    return 0 if $self->num_sold;
 
     # otherwise, same privileges as for edits
     return $self->can_be_edited_by( @_ );
@@ -640,6 +664,22 @@ sub is_untagged {
         return 1 if $id == $_->id;
     }
     return 0;  # not in the untagged list
+}
+
+sub num_sold {
+    my ( $self ) = @_;
+    my $id = $self->id or return undef;
+    my $count = LJ::MemCache::get( $self->num_sold_memkey );
+    return $count if defined $count;
+
+    # check db if not in cache
+    my $dbr = LJ::get_db_reader();
+    $count = $dbr->selectrow_array(
+             "SELECT count FROM vgift_counts WHERE vgiftid=$id" ) || 0;
+    die $dbr->errstr if $dbr->err;
+
+    LJ::MemCache::set( $self->num_sold_memkey, $count, 3600*24 );
+    return $count;
 }
 
 
@@ -733,6 +773,12 @@ sub tagged_with_memkey {
     my ( $self, $tagid )  = @_;
     return undef unless defined $tagid;
     return [$tagid, "vgift.tagid.$tagid"];  # list of gifts for this tagid
+}
+
+sub num_sold_memkey {
+    my ( $self )  = @_;
+    return undef unless my $id = $self->id;
+    return [$id, "vgift.count.$id"];
 }
 
 sub untagged_memkey { return 'vgift_untagged'; }
--------------------------------------------------------------------------------