File: index_caching.rb

package info (click to toggle)
ruby-sequel 5.63.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,408 kB
  • sloc: ruby: 113,747; makefile: 3
file content (109 lines) | stat: -rw-r--r-- 3,470 bytes parent folder | download | duplicates (3)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen-string-literal: true
#
# The index_caching extension adds a few methods to Sequel::Database
# that make it easy to dump information about database indexes to a file,
# and load it from that file.  Loading index information from a
# dumped file is faster than parsing it from the database, so this
# can save bootup time for applications with large numbers of index.
#
# Basic usage in application code:
#
#   DB = Sequel.connect('...')
#   DB.extension :index_caching
#   DB.load_index_cache('/path/to/index_cache.dump')
#
#   # load model files
#
# Then, whenever database indicies are modified, write a new cached
# file.  You can do that with <tt>bin/sequel</tt>'s -X option:
#
#   bin/sequel -X /path/to/index_cache.dump postgres://...
#
# Alternatively, if you don't want to dump the index information for
# all tables, and you don't worry about race conditions, you can
# choose to use the following in your application code:
#
#   DB = Sequel.connect('...')
#   DB.extension :index_caching
#   DB.load_index_cache?('/path/to/index_cache.dump')
#
#   # load model files
#
#   DB.dump_index_cache?('/path/to/index_cache.dump')
#
# With this method, you just have to delete the index dump file if
# the schema is modified, and the application will recreate it for you
# using just the tables that your models use.
#
# Note that it is up to the application to ensure that the dumped
# index cache reflects the current state of the database.  Sequel
# does no checking to ensure this, as checking would take time and the
# purpose of this code is to take a shortcut.
#
# The index cache is dumped in Marshal format, since it is the fastest
# and it handles all ruby objects used in the indexes hash.  Because of this,
# you should not attempt to load from an untrusted file.
#
# Related module: Sequel::IndexCaching

#
module Sequel
  module IndexCaching
    # Set index cache to the empty hash.
    def self.extended(db)
      db.instance_variable_set(:@indexes, {})
    end
    
    # Dump the index cache to the filename given in Marshal format.
    def dump_index_cache(file)
      File.open(file, 'wb'){|f| f.write(Marshal.dump(@indexes))}
      nil
    end

    # Dump the index cache to the filename given unless the file
    # already exists.
    def dump_index_cache?(file)
      dump_index_cache(file) unless File.exist?(file)
    end

    # Replace the index cache with the data from the given file, which
    # should be in Marshal format.
    def load_index_cache(file)
      @indexes = Marshal.load(File.read(file))
      nil
    end

    # Replace the index cache with the data from the given file if the
    # file exists.
    def load_index_cache?(file)
      load_index_cache(file) if File.exist?(file)
    end

    # If no options are provided and there is cached index information for
    # the table, return the cached information instead of querying the
    # database.
    def indexes(table, opts=OPTS)
      return super unless opts.empty?

      quoted_name = literal(table)
      if v = Sequel.synchronize{@indexes[quoted_name]}
        return v
      end

      result = super
      Sequel.synchronize{@indexes[quoted_name] = result}
      result
    end

    private

    # Remove the index cache for the given schema name
    def remove_cached_schema(table)
      k = quote_schema_table(table)
      Sequel.synchronize{@indexes.delete(k)}
      super
    end
  end

  Database.register_extension(:index_caching, IndexCaching)
end