Skip to content

Commit

Permalink
Add Relation::Variable::Materialized
Browse files Browse the repository at this point in the history
  • Loading branch information
dkubb committed Jul 26, 2013
1 parent 3c01131 commit 88c62b1
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 38 deletions.
2 changes: 1 addition & 1 deletion config/flay.yml
@@ -1,3 +1,3 @@
---
threshold: 41
total_score: 948
total_score: 957
43 changes: 38 additions & 5 deletions lib/axiom/relation/variable.rb
Expand Up @@ -7,6 +7,24 @@ class Relation
class Variable < Relation
include Adamantium::Mutable, Proxy

# Instantiate a new variable relation
#
# @example
# relval = Relation::Variable.new(relation)

This comment has been minimized.

Copy link
@snusnu

snusnu Jul 26, 2013

Collaborator

@dkubb should this maybe read relvar? also, i'm wondering why in the yard docs relevant for relation variables, you always write about "variable relations" while it seems to me (being a non-native english speaker) that "relation variable" seems to be the agreed upon name?

EDIT: grammar

This comment has been minimized.

Copy link
@dkubb

dkubb Jul 26, 2013

Author Owner

Good point. I will update it to the common term and fix the spelling mistake.

This comment has been minimized.

Copy link
@dkubb

dkubb Jul 26, 2013

Author Owner

@snusnu this is fixed in a6884b3

Thanks!

#
# @param [Relation] relation
#
# @return [Relation::Variable]
#
# @api public
def self.new(relation)
if equal?(Variable) && relation.materialized?
Materialized.new(relation)
else
super
end
end

# Initialize a variable relation
#
# @param [Relation] relation
Expand All @@ -15,8 +33,7 @@ class Variable < Relation
#
# @api private
def initialize(relation)
@relation = relation
@materialized = @relation.materialized?
@relation = relation
end

# Insert tuples into the variable relation
Expand All @@ -31,6 +48,7 @@ def initialize(relation)
# @api public
def insert(other)
mutate_relation(__method__, other)
self
end

# Delete tuples from the variable relation
Expand All @@ -45,6 +63,7 @@ def insert(other)
# @api public
def delete(other)
mutate_relation(__method__, other)
self
end

private
Expand All @@ -54,15 +73,29 @@ def delete(other)
# @param [Symbol] method
# @param [Enumerable] other
#
# @return [self]
# @return [undefined]
#
# @api private
def mutate_relation(*args)
@relation = relation.public_send(*args)
@relation = @relation.materialize if @materialized
self
end

# A materialized variable relation
class Materialized < self

private

# Apply the mutation operation to the relation and materialize it
#
# @return [undefined]
#
# @api private
def mutate_relation(*)
super
@relation = relation.materialize
end

end # class Materialized
end # class Variable
end # class Relation
end # module Axiom
35 changes: 35 additions & 0 deletions spec/unit/axiom/relation/variable/class_methods/new_spec.rb
@@ -0,0 +1,35 @@
# encoding: utf-8

require 'spec_helper'

describe Relation::Variable, '.new' do
subject { object.new(relation) }

let(:object) { described_class }
let(:header) { [[:id, Integer]] }
let(:body) { [[1]] }

context 'with a materialized relation' do
let(:relation) { Relation.new(header, body) }

it { should be_instance_of(described_class::Materialized) }

its(:header) { should == header }

it { should == body }

it { should be_materialized }
end

context 'with a non-materialized relation' do
let(:relation) { Relation::Base.new('users', header, body) }

it { should be_instance_of(described_class) }

its(:header) { should == header }

it { should == body }

it { should_not be_materialized }
end
end
23 changes: 7 additions & 16 deletions spec/unit/axiom/relation/variable/delete_spec.rb
Expand Up @@ -5,23 +5,14 @@
describe Relation::Variable, '#delete' do
subject { object.delete(other) }

let(:object) { Relation::Variable.new(relation) }
let(:other) { [[1]] }
let(:header) { [[:id, Integer]] }
let(:object) { described_class.new(relation) }
let(:relation) { Relation::Base.new('users', header, [[1]]) }
let(:other) { [[1]] }
let(:header) { [[:id, Integer]] }

context 'with a materialized relation' do
let(:relation) { Relation.new(header, [[1]]) }
it { should be_instance_of(described_class) }

it { should be_empty }
it { should_not be_materialized }

it { should be_materialized }
end

context 'with a non-materialized relation' do
let(:relation) { Relation::Base.new('users', header, [[1]]) }

it { should be_empty }

it { should_not be_materialized }
end
it { should be_empty }
end
23 changes: 7 additions & 16 deletions spec/unit/axiom/relation/variable/insert_spec.rb
Expand Up @@ -5,23 +5,14 @@
describe Relation::Variable, '#insert' do
subject { object.insert(other) }

let(:object) { Relation::Variable.new(relation) }
let(:other) { [[2]] }
let(:header) { [[:id, Integer]] }
let(:object) { described_class.new(relation) }
let(:relation) { Relation::Base.new('users', header, [[1]]) }
let(:other) { [[2]] }
let(:header) { [[:id, Integer]] }

context 'with a materialized relation' do
let(:relation) { Relation.new(header, [[1]]) }
it { should be_instance_of(described_class) }

it { should == [[1], [2]] }
it { should_not be_materialized }

it { should be_materialized }
end

context 'with a non-materialized relation' do
let(:relation) { Relation::Base.new('users', header, [[1]]) }

it { should == [[1], [2]] }

it { should_not be_materialized }
end
it { should == [[1], [2]] }
end
18 changes: 18 additions & 0 deletions spec/unit/axiom/relation/variable/materialized/delete_spec.rb
@@ -0,0 +1,18 @@
# encoding: utf-8

require 'spec_helper'

describe Relation::Variable::Materialized, '#delete' do
subject { object.delete(other) }

let(:object) { described_class.new(relation) }
let(:relation) { Relation.new(header, [[1]]) }
let(:other) { [[1]] }
let(:header) { [[:id, Integer]] }

it { should be_instance_of(described_class) }

it { should be_materialized }

it { should be_empty }
end
18 changes: 18 additions & 0 deletions spec/unit/axiom/relation/variable/materialized/insert_spec.rb
@@ -0,0 +1,18 @@
# encoding: utf-8

require 'spec_helper'

describe Relation::Variable::Materialized, '#insert' do
subject { object.insert(other) }

let(:object) { described_class.new(relation) }
let(:relation) { Relation.new(header, [[1]]) }
let(:other) { [[2]] }
let(:header) { [[:id, Integer]] }

it { should be_instance_of(described_class) }

it { should be_materialized }

it { should == [[1], [2]] }
end

0 comments on commit 88c62b1

Please sign in to comment.