Class: Tap::Server::Data

Inherits:
Root
  • Object
show all
Defined in:
lib/tap/server/data.rb

Overview

A very simple wrapper for root providing a CRUD interface for reading and writing files. Data ids may be integers (if you want to pretend Data is a database), or they can be relative paths.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_or_dir = Dir.pwd) ⇒ Data

Returns a new instance of Data.



11
12
13
14
15
16
17
18
19
# File 'lib/tap/server/data.rb', line 11

def initialize(config_or_dir=Dir.pwd)
  @cache = Hash.new([])
  
  if config_or_dir.kind_of?(Tap::Root)
    config_or_dir = config_or_dir.config.to_hash
  end
  
  super(config_or_dir)
end

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



9
10
11
# File 'lib/tap/server/data.rb', line 9

def cache
  @cache
end

Instance Method Details

#copy(als, id, new_id) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/tap/server/data.rb', line 140

def copy(als, id, new_id)
  path = existing_path(als, id)
  new_path = non_existant_path(als, new_id)
  
  prepare(new_path)
  FileUtils.copy(path, new_path)
  new_id
end

#create(als, id) ⇒ Object

Creates an entry (ie a file) for the specified id. Yields the open file to the block if given, otherwise the file will be created without content. Returns the path to the file.

Raises an error if the file already exists.



79
80
81
82
# File 'lib/tap/server/data.rb', line 79

def create(als, id)
  path = non_existant_path(als, id)
  create!(path) {|io| yield(io) if block_given? }
end

#create_or_update(als, id) ⇒ Object



111
112
113
114
# File 'lib/tap/server/data.rb', line 111

def create_or_update(als, id)
  path = entry_path(als, id)
  create!(path) {|io| yield(io) }
end

#destroy(als, id) ⇒ Object

Removes the specified entry (ie file), if it exists. Returns true if the file was removed and false otherwise.



101
102
103
104
105
106
107
108
109
# File 'lib/tap/server/data.rb', line 101

def destroy(als, id)
  if path = find(als, id)
    FileUtils.rm(path)
    cache[als].delete(id)
    true
  else
    false
  end
end

#entries(als) ⇒ Object

Returns a list of entry paths.



38
39
40
41
42
# File 'lib/tap/server/data.rb', line 38

def entries(als)
  glob(als).select do |path|
    File.file?(path)
  end
end

#entry_path(als, id) ⇒ Object

A restricted version of the original. Path raises an error if the final path is not relative to als.



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/tap/server/data.rb', line 23

def entry_path(als, id)
  id = id.to_s
  if id.empty?
    raise "no id specified" 
  end
  
  path = self.path(als, id)
  unless relative?(als, path)
    raise "not a subpath: #{id.inspect} (#{als.inspect})"
  end
  
  path
end

#find(als, id) ⇒ Object

Returns the path for the specified entry, if it exists. Returns nil if no such entry can be found.



67
68
69
70
71
72
# File 'lib/tap/server/data.rb', line 67

def find(als, id)
  return nil unless id
  
  path = entry_path(als, id)
  File.file?(path) ? path : nil
end

#import(als, upload, id = nil) ⇒ Object



116
117
118
119
120
121
122
123
# File 'lib/tap/server/data.rb', line 116

def import(als, upload, id=nil)
  id = upload[:filename] unless id && !id.empty?
  path = non_existant_path(als, id)
  
  prepare(path)
  FileUtils.mv(upload[:tempfile].path, path)
  path
end

#index(als) ⇒ Object

Returns a list of existing ids.



45
46
47
48
49
# File 'lib/tap/server/data.rb', line 45

def index(als)
  entries(als).collect do |path|
    relative_path(als, path)
  end
end

#move(als, id, new_id) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/tap/server/data.rb', line 125

def move(als, id, new_id)
  path = existing_path(als, id)
  new_path = non_existant_path(als, new_id)
  
  prepare(new_path)
  FileUtils.mv(path, new_path)
  
  if cache[als].include?(id)
    cache[als].delete(id)
    cache[als] << new_id
  end
  
  new_id
end

#next_id(als) ⇒ Object

Returns an available integer id, usually the number of entries in self, but a random integer is generated if that number is taken.



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/tap/server/data.rb', line 53

def next_id(als)
  # try the next in the sequence
  id = entries(als).length
  
  # if that already exists, go for a random id
  while find(als, id)
    id = rand(id * 10000)
  end
  
  id
end

#read(als, id) ⇒ Object

Reads and returns the data for the specified entry, or nil if the entry doesn’t exist.



86
87
88
89
# File 'lib/tap/server/data.rb', line 86

def read(als, id)
  path = find(als, id)
  path ? File.read(path) : nil
end

#update(als, id) ⇒ Object

Overwrites the data for the specified entry. A block must be given to provide the new content; an error is raised if the entry does not already exist.



94
95
96
97
# File 'lib/tap/server/data.rb', line 94

def update(als, id)
  path = existing_path(als, id)
  create!(path) {|io| yield(io) }
end