summaryrefslogtreecommitdiff
path: root/lib/tapicero/couch_changes.rb
blob: b45d54a4190afc7c27738f142dc330bf4ad3b784 (plain)
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
require 'couchrest'
require 'fileutils'

module Tapicero
  class CouchChanges

    attr_accessor :db

    def initialize(db, seq_filename)
      @db = db
      @seq_filename = seq_filename
      read_seq(seq_filename)
    end

    def created(hash = {}, &block)
      if block_given?
        @created = block
      else
        @created && @created.call(hash)
      end
    end

    def deleted(hash = {}, &block)
      if block_given?
        @deleted = block
      else
        @deleted && @deleted.call(hash)
      end
    end

    def listen
      Tapicero.logger.info "listening..."
      Tapicero.logger.debug "Starting at sequence #{since}"
      db.changes :feed => :continuous, :since => since, :heartbeat => 1000 do |hash|
        callbacks(hash)
        store_seq(hash["seq"])
      end
    end

    protected

    def since
      @since ||= 0  # fetch_last_seq
    end

    def callbacks(hash)
      #changed callback
      return unless changes = hash["changes"]
      return deleted(hash) if hash["deleted"]
      created(hash) if changes[0]["rev"].start_with?('1-')
      #updated callback
    end

    def read_seq(seq_filename)
      Tapicero.logger.debug "Looking up sequence here: #{seq_filename}"
      FileUtils.touch(seq_filename)
      unless File.writable?(seq_filename)
        raise StandardError.new("Can't access sequence file")
      end
      @since = File.read(seq_filename).to_i
      Tapicero.logger.debug "Found sequence: #{@since}"
    rescue Errno::ENOENT => e
      Tapicero.logger.warn "No sequence file found. Starting from scratch"
    end

    def store_seq(seq)
      File.write(@seq_filename, seq)
    end

    #
    # UNUSED: this is useful for only following new sequences.
    #
    def fetch_last_seq
      hash = db.changes :limit => 1, :descending => true
      Tapicero.logger.info "starting at seq: " + hash["last_seq"]
      return hash["last_seq"]
    end

  end
end