turntable 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +50 -0
- data/TODO +18 -0
- data/lib/turntable.rb +14 -0
- data/lib/turntable/columndefinition.rb +39 -0
- data/lib/turntable/row.rb +42 -0
- data/lib/turntable/table.rb +64 -0
- data/lib/turntable/tableheader.rb +49 -0
- metadata +78 -0
data/README
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Turntable
|
|
3
|
+
# The hip-hop Ruby database
|
|
4
|
+
#
|
|
5
|
+
# Christian Koch <cfkoch@sdf.lonestar.org>
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
Turntable is a pure Ruby implementation of a relational database, similar in
|
|
9
|
+
spirit to SQLite. Unlike Sequel or any other object-relational mapper, Turntable
|
|
10
|
+
is built with Ruby from the ground up, and implements Rubyisms whenever
|
|
11
|
+
possible. It never goes anywhere near SQL.
|
|
12
|
+
|
|
13
|
+
Turntable databases include the Enumerable mixin, so all the methods available
|
|
14
|
+
there are also available for you:
|
|
15
|
+
|
|
16
|
+
turntable.
|
|
17
|
+
select { |film| film[:title] =~ /\AG/ }.
|
|
18
|
+
sort_by { |film| film[:year] }.
|
|
19
|
+
reverse.
|
|
20
|
+
detect { |film| film[:director] == "Francis Ford Coppola" }
|
|
21
|
+
|
|
22
|
+
#####
|
|
23
|
+
|
|
24
|
+
Turntable is released under a simplified BSD-style license.
|
|
25
|
+
|
|
26
|
+
Copyright (c) 2011 Christian Koch
|
|
27
|
+
All rights reserved.
|
|
28
|
+
|
|
29
|
+
Redistribution and use in source and binary forms, with or without
|
|
30
|
+
modification, are permitted provided that the following conditions
|
|
31
|
+
are met:
|
|
32
|
+
|
|
33
|
+
1. Redistributions of source code must retain the above copyright
|
|
34
|
+
notice, this list of conditions and the following disclaimer.
|
|
35
|
+
|
|
36
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
37
|
+
notice, this list of conditions and the following disclaimer in the
|
|
38
|
+
documentation and/or other materials provided with the distribution.
|
|
39
|
+
|
|
40
|
+
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
41
|
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
42
|
+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
43
|
+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
44
|
+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
45
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
46
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
47
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
48
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
49
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
50
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/TODO
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
In no particular order:
|
|
2
|
+
|
|
3
|
+
* Somehow make every Row aware of its associated TableHeader without actually
|
|
4
|
+
shipping every Row with the TableHeader.
|
|
5
|
+
|
|
6
|
+
* Make Turntable marshallable.
|
|
7
|
+
|
|
8
|
+
* Figure out the best/most efficient way to serialize increasingly larger
|
|
9
|
+
tables.
|
|
10
|
+
|
|
11
|
+
* Implement all of the SortedSet methods which are not present in Enumerable in
|
|
12
|
+
such a way that does not require calling Turntable::Table#rows. (#delete_if,
|
|
13
|
+
first, etc.)
|
|
14
|
+
|
|
15
|
+
* Write simpler #inspect representations of all objects.
|
|
16
|
+
|
|
17
|
+
* Add the strict typing functionality, or figure out what to do with it at
|
|
18
|
+
least.
|
data/lib/turntable.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#
|
|
2
|
+
# columndefinition.rb
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
module Turntable
|
|
6
|
+
|
|
7
|
+
# A Turntable::ColumnDefinition consists of a name, its position within a
|
|
8
|
+
# Turntable::TableHeader, and, optionally, its associated type.
|
|
9
|
+
#
|
|
10
|
+
# ColumnDefinitions are meant to be created and manipulated by a TableHeader.
|
|
11
|
+
# ColumnDefinition and its methods are not intended to be used directly by the
|
|
12
|
+
# end user.
|
|
13
|
+
#
|
|
14
|
+
class ColumnDefinition
|
|
15
|
+
|
|
16
|
+
include Comparable
|
|
17
|
+
|
|
18
|
+
# A ColumnDefinition is ``less than'' another if its position is smaller.
|
|
19
|
+
# Likewise, a ColumnDefinition is ``greater than'' another if its position
|
|
20
|
+
# is greater.
|
|
21
|
+
#
|
|
22
|
+
def <=>(another)
|
|
23
|
+
(self.position > another.position) ? (1) : (-1)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_accessor :name
|
|
27
|
+
attr_reader :position, :type
|
|
28
|
+
|
|
29
|
+
# Creates a new ColumnDefinition. This method should not be used directly.
|
|
30
|
+
# Instead, create a new Turntable::TableHeader.
|
|
31
|
+
#
|
|
32
|
+
def initialize(name, position, type=nil)
|
|
33
|
+
@name = name
|
|
34
|
+
@position = position
|
|
35
|
+
@type = type
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#
|
|
2
|
+
# row.rb
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
require 'turntable/tableheader'
|
|
6
|
+
|
|
7
|
+
module Turntable
|
|
8
|
+
|
|
9
|
+
# A Turntable::Row represents one row in a Turntable::Table, according to the
|
|
10
|
+
# table's Turntable::TableHeader.
|
|
11
|
+
#
|
|
12
|
+
class Row
|
|
13
|
+
|
|
14
|
+
include Comparable
|
|
15
|
+
|
|
16
|
+
# A Row is ``less than'' another if its position is smaller. Likewise, a Row
|
|
17
|
+
# is ``greater than'' another if its position is larger.
|
|
18
|
+
#
|
|
19
|
+
def <=>(another)
|
|
20
|
+
(self.position > another.position) ? (1) : (-1)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attr_reader :data, :position
|
|
24
|
+
|
|
25
|
+
# This method is not meant to be used directly. Refer to Turntable::Table.
|
|
26
|
+
#
|
|
27
|
+
def initialize(header, position, data_array)
|
|
28
|
+
@header = header # FIXME This makes IRB really ugly
|
|
29
|
+
@position = position
|
|
30
|
+
@data = data_array
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Returns the data found at a specific column.
|
|
34
|
+
# TODO @data should have this close by...
|
|
35
|
+
#
|
|
36
|
+
def [](column_name)
|
|
37
|
+
i = @header.detect { |column| column.name == column_name }.position
|
|
38
|
+
@data[i]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#
|
|
2
|
+
# table.rb
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
require 'set'
|
|
6
|
+
require 'turntable/row'
|
|
7
|
+
|
|
8
|
+
module Turntable
|
|
9
|
+
|
|
10
|
+
# Turntable::Table is Turntable's main interface. It maintains an ordered list
|
|
11
|
+
# of Turntable::Row objects, according to a given Turntable::TableHeader.
|
|
12
|
+
#
|
|
13
|
+
# Internally, Turntable::Table implements a SortedSet. See the documentation
|
|
14
|
+
# for Turntable::TableHeader for the reasons why. Additionally, the SortedSet
|
|
15
|
+
# ensures that two otherwise identical rows will have differing positions
|
|
16
|
+
# within the table.
|
|
17
|
+
#
|
|
18
|
+
# Turntable::Table includes Enumerable, so every method there is available
|
|
19
|
+
# here. Also, calling Turntable::Table#rows returns the internal SortedSet, so
|
|
20
|
+
# you can gain access to the instance methods available for sets that way.
|
|
21
|
+
class Table
|
|
22
|
+
|
|
23
|
+
include Enumerable
|
|
24
|
+
|
|
25
|
+
def each
|
|
26
|
+
@rows.each { |row| yield row }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
attr_reader :header
|
|
30
|
+
attr_accessor :rows
|
|
31
|
+
|
|
32
|
+
# Associates a TableHeader with a new, empty Table.
|
|
33
|
+
#
|
|
34
|
+
def initialize(header)
|
|
35
|
+
@rows = SortedSet.new
|
|
36
|
+
@header = header
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Append a new Row to the Table.
|
|
40
|
+
#
|
|
41
|
+
# t = Turntable::Table.new(some_header)
|
|
42
|
+
# t.push "LP4", "Ratatat", 2010
|
|
43
|
+
#
|
|
44
|
+
def push(*data)
|
|
45
|
+
r = Row.new(@header, get_new_position, data)
|
|
46
|
+
@rows << r
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Determines the position of a new row. If there are no rows, then simply
|
|
50
|
+
# return 0.
|
|
51
|
+
#
|
|
52
|
+
def get_new_position
|
|
53
|
+
(@rows.empty?) ? (0) : (@rows.sort.last.position + 1)
|
|
54
|
+
end
|
|
55
|
+
private :get_new_position
|
|
56
|
+
|
|
57
|
+
# Retreives a row by its position.
|
|
58
|
+
#
|
|
59
|
+
def [](position)
|
|
60
|
+
@rows.detect { |row| row.position == position }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# tableheader.rb
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
require 'set'
|
|
6
|
+
require 'turntable/columndefinition'
|
|
7
|
+
|
|
8
|
+
module Turntable
|
|
9
|
+
|
|
10
|
+
# A Turntable::TableHeader maintains an ordered list of ColumnDefinition
|
|
11
|
+
# objects. This list is implemented as a SortedSet for three reasons:
|
|
12
|
+
#
|
|
13
|
+
# * It's apparently faster than Array.
|
|
14
|
+
# * The columns appear in order in IRB.
|
|
15
|
+
# * It ensures there are no duplicate column definitions.
|
|
16
|
+
#
|
|
17
|
+
class TableHeader
|
|
18
|
+
|
|
19
|
+
include Enumerable
|
|
20
|
+
|
|
21
|
+
def each
|
|
22
|
+
@columns.each { |column| yield column }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_reader :columns
|
|
26
|
+
|
|
27
|
+
# Creates a new TableHeader. The given column names should be symbols.
|
|
28
|
+
#
|
|
29
|
+
# Turntable::TableHeader.new(:album, :artist, :year)
|
|
30
|
+
#
|
|
31
|
+
def initialize(*column_names)
|
|
32
|
+
@columns = SortedSet.new
|
|
33
|
+
column_names.each_with_index do |column, i|
|
|
34
|
+
@columns << Turntable::ColumnDefinition.new(column, i)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Returns a ColumnDefinition by specifying its position within the
|
|
39
|
+
# TableHeader.
|
|
40
|
+
#
|
|
41
|
+
# th = Turntable::TableHeader.new(:album, :artist, :year)
|
|
42
|
+
# th[1] # => #<Turntable::ColumnDefinition @name=... @position=...>
|
|
43
|
+
#
|
|
44
|
+
def [](position)
|
|
45
|
+
@columns.detect { |column| column.position == position }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: turntable
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Christian Koch
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-03-31 00:00:00 -07:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies: []
|
|
21
|
+
|
|
22
|
+
description: |
|
|
23
|
+
Turntable is a pure Ruby implementation of a relational database, similar in
|
|
24
|
+
spirit to SQLite. Unlike Sequel or any other object-relational mapper, Turntable
|
|
25
|
+
is built with Ruby from the ground up, and implements Rubyisms whenever
|
|
26
|
+
possible.
|
|
27
|
+
|
|
28
|
+
email: cfkoch@sdf.lonestar.org
|
|
29
|
+
executables: []
|
|
30
|
+
|
|
31
|
+
extensions: []
|
|
32
|
+
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
|
|
35
|
+
files:
|
|
36
|
+
- README
|
|
37
|
+
- TODO
|
|
38
|
+
- lib/turntable.rb
|
|
39
|
+
- lib/turntable/columndefinition.rb
|
|
40
|
+
- lib/turntable/row.rb
|
|
41
|
+
- lib/turntable/table.rb
|
|
42
|
+
- lib/turntable/tableheader.rb
|
|
43
|
+
has_rdoc: true
|
|
44
|
+
homepage:
|
|
45
|
+
licenses:
|
|
46
|
+
- 2-clause BSD
|
|
47
|
+
post_install_message:
|
|
48
|
+
rdoc_options: []
|
|
49
|
+
|
|
50
|
+
require_paths:
|
|
51
|
+
- - lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
none: false
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
hash: 3
|
|
58
|
+
segments:
|
|
59
|
+
- 0
|
|
60
|
+
version: "0"
|
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
|
+
none: false
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
hash: 3
|
|
67
|
+
segments:
|
|
68
|
+
- 0
|
|
69
|
+
version: "0"
|
|
70
|
+
requirements: []
|
|
71
|
+
|
|
72
|
+
rubyforge_project:
|
|
73
|
+
rubygems_version: 1.3.7
|
|
74
|
+
signing_key:
|
|
75
|
+
specification_version: 3
|
|
76
|
+
summary: The hip-hop Ruby database.
|
|
77
|
+
test_files: []
|
|
78
|
+
|