class Silly::Query

Constants

BlackList
FileAttributes

Attributes

paths[RW]

Public Class Methods

new() click to toggle source
# File lib/silly.rb, line 25
def initialize
  @criteria = {
    "path" => nil,
    "sort" => ["id", "asc"],
    "where" => [],
  }
  @paths = Set.new
end

Public Instance Methods

append_path(path) click to toggle source
# File lib/silly.rb, line 34
def append_path(path)
  @paths << path
end
each() { |a| ... } click to toggle source
# File lib/silly.rb, line 59
def each
  block_given? ?
    execute.each { |a| yield(a) } :
    execute
end
execute() click to toggle source
# File lib/silly.rb, line 65
def execute
  @criteria["path"] ||= "*"
  puts "EXECUTE:\n #{ @criteria.inspect }"
  data = files(@criteria["path"])

  unless @criteria["where"].empty?
    data = data.keep_if { |id, pointer| filter_function(pointer) }
  end

  data = data.values.sort { |a,b| sorting_function(a,b) }

  Silly::Collection.new(data)
end
inspect() click to toggle source
# File lib/silly.rb, line 91
def inspect
  "#{ self.class.name }\n criteria:\n #{ @criteria.inspect }"
end
list() click to toggle source
# File lib/silly.rb, line 79
def list
  results = Set.new

  paths.each do |path|
    FileUtils.cd(path) {
      results += Dir['*'].select { |x| File.directory?(x) }
    }
  end

  results.to_a
end
path(path) click to toggle source
# File lib/silly.rb, line 39
def path(path)
  @criteria["path"] = BlackList.include?(path.to_s) ? "*" : File.join(path, "*")
  self
end
path_all(path) click to toggle source
# File lib/silly.rb, line 44
def path_all(path)
  @criteria["path"] = File.join(path, "**", "**")
  self
end
sort(conditions=[]) click to toggle source
# File lib/silly.rb, line 49
def sort(conditions=[])
  @criteria["sort"] = conditions
  self
end
where(conditions) click to toggle source
# File lib/silly.rb, line 54
def where(conditions)
  @criteria["where"] << conditions
  self
end

Private Instance Methods

files(glob) click to toggle source

Collect all files for the given @collection. Each item can have 3 file references, one per each cascade level. The file hashes are collected in order so they will overwrite eachother. but references to all found items on the cascade are recorded. @return dictionary of Items.

# File lib/silly.rb, line 102
def files(glob)
  dict = {}

  paths.each do |path|
    FileUtils.cd(path) {
      Dir[glob].each { |id|
        next unless File.exist?(id) && FileTest.file?(id)

        filename = id.gsub(Regexp.new("#{ File.extname(id) }$"), '')

        if dict[filename]
          dict[filename]["cascade"] << File.realpath(id)
        else
          dict[filename] = Silly::Item.new({
            "id" => id,
            "cascade" => [File.realpath(id)]
          })
        end
      }
    }
  end

  dict
end
filter_function(item) click to toggle source
# File lib/silly.rb, line 129
def filter_function(item)
  @criteria["where"].each do |condition|
    condition.each do |attribute_name, value|
      attribute_name = attribute_name.to_s
      attribute = attribute_name[0] == "$" ?
                    item.__send__(attribute_name[1, attribute_name.size]) :
                    item.data[attribute_name]

      valid = Silly::QueryOperators.execute(attribute, value)

      return false unless valid
    end
  end
end
sorting_function(a, b) click to toggle source
# File lib/silly.rb, line 144
def sorting_function(a, b)
  attribute = @criteria["sort"][0].to_s
  direction = @criteria["sort"][1].to_s

  # Optmization to omit parsing internal metadata when unecessary.
  if FileAttributes.include?(attribute)
    this_data = a.__send__(attribute)
    other_data = b.__send__(attribute)
  else
    this_data = a.data[attribute]
    other_data = b.data[attribute]
  end

  if attribute == "date"
    if this_data.nil? || other_data.nil?
      raise(
        "ArgumentError:" +
        " The query is sorting on 'date'" +
        " but '#{ this_data['id'] }' or '#{ other_data['id'] }' has no parseable date in its metadata." +
        " Add date: 'YYYY-MM-DD' to its metadata."
      )
    end
  end

  if direction == "asc"
    this_data <=> other_data
  else
    other_data <=> this_data
  end
end