Class: Linkage::Function Abstract

Inherits:
Data
  • Object
show all
Defined in:
lib/linkage/function.rb

Overview

This class is abstract.

Abstract class to represent SQL functions. No attempts are made to ensure that the function actually exists in the database you’re using.

Constant Summary

Constants inherited from Data

Data::TYPE_CONVERSION_TREE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Data

#database_type, #merge

Constructor Details

#initialize(*args) ⇒ Function

Creates a new Function object. If the arguments contain only static objects, you should specify the dataset that this function belongs to as the last argument like so:

Function.new(foo, bar, :dataset => dataset)

Optionally, you can use the ‘dataset=` setter to do it later. Many functions require a dataset to work properly. If you try to use such a function without setting a dataset, it will raise a RuntimeError.

Parameters:



54
55
56
57
58
59
# File 'lib/linkage/function.rb', line 54

def initialize(*args)
  @names = [self.class.function_name]
  @args = args
  @options = args.last.is_a?(Hash) ? args.pop : {}
  process_args
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



41
42
43
# File 'lib/linkage/function.rb', line 41

def args
  @args
end

Class Method Details

.[](name) ⇒ Object



19
20
21
# File 'lib/linkage/function.rb', line 19

def self.[](name)
  @functions ? @functions[name] : nil
end

.function_nameObject

Subclasses must define this.

Raises:

  • (NotImplementedError)


24
25
26
# File 'lib/linkage/function.rb', line 24

def self.function_name
  raise NotImplementedError
end

.parametersObject

Subclasses can define this to require a specific number of arguments of a certain class. To require two parameters of either String or Integer, do something like this:

@@parameters = [[String, Integer], [String, Integer]]
def self.parameters
  @@parameters
end


37
38
39
# File 'lib/linkage/function.rb', line 37

def self.parameters
  nil
end

.register(klass) ⇒ Object

Register a new function.

Parameters:



10
11
12
13
14
15
16
17
# File 'lib/linkage/function.rb', line 10

def self.register(klass)
  if klass.instance_methods(false).any? { |m| m.to_s == "ruby_type" }
    @functions ||= {}
    @functions[klass.function_name] = klass
  else
    raise ArgumentError, "ruby_type instance method must be defined"
  end
end

Instance Method Details

#==(other) ⇒ Object



80
81
82
# File 'lib/linkage/function.rb', line 80

def ==(other)
  equal?(other) || (other.is_a?(Function) && name == other.name && args == other.args && dataset == other.dataset)
end

#collationObject

Returns ‘nil` by default. Subclasses should redefine this if there is a collation.



94
95
96
# File 'lib/linkage/function.rb', line 94

def collation
  nil
end

#datasetObject



65
66
67
68
69
70
# File 'lib/linkage/function.rb', line 65

def dataset
  if @dataset.nil?
    raise RuntimeError, "You must specify a dataset for static functions"
  end
  @dataset
end

#dataset=(dataset) ⇒ Object



72
73
74
# File 'lib/linkage/function.rb', line 72

def dataset=(dataset)
  @dataset = dataset
end

#nameObject



61
62
63
# File 'lib/linkage/function.rb', line 61

def name
  @name ||= @names.join("_").to_sym
end

#ruby_typeObject

Subclasses must define this. The return value should be a Hash with the following elements:

:type - column type (Ruby class) of the result
:opts - Optional hash with additional options (like :size)

Raises:

  • (NotImplementedError)


88
89
90
# File 'lib/linkage/function.rb', line 88

def ruby_type
  raise NotImplementedError
end

#static?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/linkage/function.rb', line 76

def static?
  @static
end

#to_expr(options = {}) ⇒ Sequel::SQL::Function

Returns:

  • (Sequel::SQL::Function)


99
100
101
# File 'lib/linkage/function.rb', line 99

def to_expr(options = {})
  self.class.function_name.to_sym.sql_function(*@values)
end