cequel 0.5.6 → 1.0.0.pre.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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cequel.rb +5 -8
  3. data/lib/cequel/errors.rb +1 -0
  4. data/lib/cequel/metal.rb +17 -0
  5. data/lib/cequel/metal/batch.rb +62 -0
  6. data/lib/cequel/metal/cql_row_specification.rb +26 -0
  7. data/lib/cequel/metal/data_set.rb +461 -0
  8. data/lib/cequel/metal/deleter.rb +47 -0
  9. data/lib/cequel/metal/incrementer.rb +35 -0
  10. data/lib/cequel/metal/inserter.rb +53 -0
  11. data/lib/cequel/metal/keyspace.rb +213 -0
  12. data/lib/cequel/metal/row.rb +48 -0
  13. data/lib/cequel/metal/row_specification.rb +37 -0
  14. data/lib/cequel/metal/statement.rb +30 -0
  15. data/lib/cequel/metal/updater.rb +65 -0
  16. data/lib/cequel/metal/writer.rb +73 -0
  17. data/lib/cequel/model.rb +12 -84
  18. data/lib/cequel/model/association_collection.rb +23 -0
  19. data/lib/cequel/model/associations.rb +84 -80
  20. data/lib/cequel/model/base.rb +74 -0
  21. data/lib/cequel/model/belongs_to_association.rb +31 -0
  22. data/lib/cequel/model/callbacks.rb +14 -10
  23. data/lib/cequel/model/collection.rb +255 -0
  24. data/lib/cequel/model/errors.rb +6 -6
  25. data/lib/cequel/model/has_many_association.rb +26 -0
  26. data/lib/cequel/model/mass_assignment.rb +31 -0
  27. data/lib/cequel/model/persistence.rb +119 -115
  28. data/lib/cequel/model/properties.rb +89 -87
  29. data/lib/cequel/model/railtie.rb +21 -14
  30. data/lib/cequel/model/record_set.rb +285 -0
  31. data/lib/cequel/model/schema.rb +33 -0
  32. data/lib/cequel/model/scoped.rb +5 -48
  33. data/lib/cequel/model/validations.rb +18 -18
  34. data/lib/cequel/schema.rb +15 -0
  35. data/lib/cequel/schema/column.rb +135 -0
  36. data/lib/cequel/schema/create_table_dsl.rb +56 -0
  37. data/lib/cequel/schema/keyspace.rb +50 -0
  38. data/lib/cequel/schema/table.rb +120 -0
  39. data/lib/cequel/schema/table_property.rb +67 -0
  40. data/lib/cequel/schema/table_reader.rb +139 -0
  41. data/lib/cequel/schema/table_synchronizer.rb +114 -0
  42. data/lib/cequel/schema/table_updater.rb +83 -0
  43. data/lib/cequel/schema/table_writer.rb +80 -0
  44. data/lib/cequel/schema/update_table_dsl.rb +60 -0
  45. data/lib/cequel/type.rb +232 -0
  46. data/lib/cequel/version.rb +1 -1
  47. data/spec/environment.rb +5 -1
  48. data/spec/examples/metal/data_set_spec.rb +608 -0
  49. data/spec/examples/model/associations_spec.rb +84 -74
  50. data/spec/examples/model/callbacks_spec.rb +66 -59
  51. data/spec/examples/model/list_spec.rb +393 -0
  52. data/spec/examples/model/map_spec.rb +229 -0
  53. data/spec/examples/model/mass_assignment_spec.rb +55 -0
  54. data/spec/examples/model/naming_spec.rb +11 -4
  55. data/spec/examples/model/persistence_spec.rb +140 -150
  56. data/spec/examples/model/properties_spec.rb +122 -75
  57. data/spec/examples/model/record_set_spec.rb +285 -0
  58. data/spec/examples/model/schema_spec.rb +44 -0
  59. data/spec/examples/model/serialization_spec.rb +20 -14
  60. data/spec/examples/model/set_spec.rb +133 -0
  61. data/spec/examples/model/spec_helper.rb +0 -10
  62. data/spec/examples/model/validations_spec.rb +51 -38
  63. data/spec/examples/schema/table_reader_spec.rb +328 -0
  64. data/spec/examples/schema/table_synchronizer_spec.rb +172 -0
  65. data/spec/examples/schema/table_updater_spec.rb +157 -0
  66. data/spec/examples/schema/table_writer_spec.rb +225 -0
  67. data/spec/examples/spec_helper.rb +29 -0
  68. data/spec/examples/type_spec.rb +204 -0
  69. data/spec/support/helpers.rb +67 -8
  70. metadata +121 -152
  71. data/lib/cequel/batch.rb +0 -58
  72. data/lib/cequel/cql_row_specification.rb +0 -22
  73. data/lib/cequel/data_set.rb +0 -371
  74. data/lib/cequel/keyspace.rb +0 -205
  75. data/lib/cequel/model/class_internals.rb +0 -49
  76. data/lib/cequel/model/column.rb +0 -20
  77. data/lib/cequel/model/counter.rb +0 -35
  78. data/lib/cequel/model/dictionary.rb +0 -126
  79. data/lib/cequel/model/dirty.rb +0 -53
  80. data/lib/cequel/model/dynamic.rb +0 -31
  81. data/lib/cequel/model/inheritable.rb +0 -48
  82. data/lib/cequel/model/instance_internals.rb +0 -23
  83. data/lib/cequel/model/local_association.rb +0 -42
  84. data/lib/cequel/model/magic.rb +0 -79
  85. data/lib/cequel/model/mass_assignment_security.rb +0 -21
  86. data/lib/cequel/model/naming.rb +0 -17
  87. data/lib/cequel/model/observer.rb +0 -42
  88. data/lib/cequel/model/readable_dictionary.rb +0 -182
  89. data/lib/cequel/model/remote_association.rb +0 -40
  90. data/lib/cequel/model/scope.rb +0 -362
  91. data/lib/cequel/model/subclass_internals.rb +0 -45
  92. data/lib/cequel/model/timestamps.rb +0 -52
  93. data/lib/cequel/model/translation.rb +0 -17
  94. data/lib/cequel/row_specification.rb +0 -63
  95. data/lib/cequel/statement.rb +0 -23
  96. data/spec/examples/data_set_spec.rb +0 -444
  97. data/spec/examples/keyspace_spec.rb +0 -84
  98. data/spec/examples/model/counter_spec.rb +0 -94
  99. data/spec/examples/model/dictionary_spec.rb +0 -301
  100. data/spec/examples/model/dirty_spec.rb +0 -39
  101. data/spec/examples/model/dynamic_spec.rb +0 -41
  102. data/spec/examples/model/inheritable_spec.rb +0 -45
  103. data/spec/examples/model/magic_spec.rb +0 -199
  104. data/spec/examples/model/mass_assignment_security_spec.rb +0 -13
  105. data/spec/examples/model/observer_spec.rb +0 -86
  106. data/spec/examples/model/scope_spec.rb +0 -677
  107. data/spec/examples/model/timestamps_spec.rb +0 -52
  108. data/spec/examples/model/translation_spec.rb +0 -23
@@ -0,0 +1,15 @@
1
+ require 'cequel/schema/column'
2
+ require 'cequel/schema/create_table_dsl'
3
+ require 'cequel/schema/keyspace'
4
+ require 'cequel/schema/table'
5
+ require 'cequel/schema/table_property'
6
+ require 'cequel/schema/table_reader'
7
+ require 'cequel/schema/table_synchronizer'
8
+ require 'cequel/schema/table_updater'
9
+ require 'cequel/schema/table_writer'
10
+ require 'cequel/schema/update_table_dsl'
11
+
12
+ module Cequel
13
+ module Schema
14
+ end
15
+ end
@@ -0,0 +1,135 @@
1
+ module Cequel
2
+
3
+ module Schema
4
+
5
+ class Column
6
+
7
+ attr_reader :name, :type
8
+
9
+ def initialize(name, type)
10
+ @name, @type = name, type
11
+ end
12
+
13
+ def to_cql
14
+ "#{@name} #{@type}"
15
+ end
16
+
17
+ def cast(value)
18
+ @type.cast(value)
19
+ end
20
+
21
+ def ==(other)
22
+ to_cql == other.to_cql
23
+ end
24
+
25
+ def to_s
26
+ name
27
+ end
28
+
29
+ def inspect
30
+ %Q(#<#{self.class.name}: #{to_cql}>)
31
+ end
32
+
33
+ end
34
+
35
+ class PartitionKey < Column
36
+
37
+ def partition_key?
38
+ true
39
+ end
40
+
41
+ end
42
+
43
+ class ClusteringColumn < Column
44
+
45
+ attr_reader :clustering_order
46
+
47
+ def initialize(name, type, clustering_order = nil)
48
+ super(name, type)
49
+ @clustering_order = (clustering_order || :asc).to_sym
50
+ end
51
+
52
+ def clustering_order_cql
53
+ "#{@name} #{@clustering_order}"
54
+ end
55
+
56
+ def partition_key?
57
+ false
58
+ end
59
+
60
+ end
61
+
62
+ class DataColumn < Column
63
+
64
+ attr_reader :index_name
65
+
66
+ def initialize(name, type, index_name = nil)
67
+ super(name, type)
68
+ @index_name = index_name
69
+ end
70
+
71
+ def indexed?
72
+ !!@index_name
73
+ end
74
+
75
+ end
76
+
77
+ class CollectionColumn < Column
78
+
79
+ def indexed?
80
+ false
81
+ end
82
+
83
+ end
84
+
85
+ class List < CollectionColumn
86
+
87
+ def to_cql
88
+ "#{@name} LIST <#{@type}>"
89
+ end
90
+
91
+ def cast(value)
92
+ value.map { |element| @type.cast(element) }
93
+ end
94
+
95
+ end
96
+
97
+ class Set < CollectionColumn
98
+
99
+ def to_cql
100
+ "#{@name} SET <#{@type}>"
101
+ end
102
+
103
+ def cast(value)
104
+ value.each_with_object(::Set[]) do |element, set|
105
+ set << @type.cast(element)
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ class Map < CollectionColumn
112
+
113
+ attr_reader :key_type
114
+ alias_method :value_type, :type
115
+
116
+ def initialize(name, key_type, value_type)
117
+ super(name, value_type)
118
+ @key_type = key_type
119
+ end
120
+
121
+ def to_cql
122
+ "#{@name} MAP <#{@key_type}, #{@type}>"
123
+ end
124
+
125
+ def cast(value)
126
+ value.each_with_object({}) do |(key, element), hash|
127
+ hash[@key_type.cast(key)] = @type.cast(element)
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,56 @@
1
+ module Cequel
2
+
3
+ module Schema
4
+
5
+ class CreateTableDSL < BasicObject
6
+
7
+ def self.apply(table, &block)
8
+ dsl = new(table)
9
+ dsl.instance_eval(&block)
10
+ end
11
+
12
+ def initialize(table)
13
+ @table = table
14
+ end
15
+
16
+ def partition_key(name, type)
17
+ @table.add_partition_key(name, type)
18
+ end
19
+
20
+ def key(name, type, clustering_order = nil)
21
+ @table.add_key(name, type, clustering_order)
22
+ end
23
+
24
+ def column(name, type, options = {})
25
+ column = @table.add_data_column(name, type, options[:index])
26
+ end
27
+
28
+ def list(name, type)
29
+ @table.add_list(name, type)
30
+ end
31
+
32
+ def set(name, type)
33
+ @table.add_set(name, type)
34
+ end
35
+
36
+ def map(name, key_type, value_type)
37
+ @table.add_map(
38
+ name,
39
+ key_type,
40
+ value_type
41
+ )
42
+ end
43
+
44
+ def with(name, value)
45
+ @table.add_property(name, value)
46
+ end
47
+
48
+ def compact_storage
49
+ @table.compact_storage = true
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,50 @@
1
+ module Cequel
2
+
3
+ module Schema
4
+
5
+ class Keyspace
6
+
7
+ def initialize(keyspace)
8
+ @keyspace = keyspace
9
+ end
10
+
11
+ def read_table(name)
12
+ TableReader.read(keyspace, name)
13
+ end
14
+
15
+ def create_table(name, &block)
16
+ table = Table.new(name)
17
+ CreateTableDSL.apply(table, &block)
18
+ TableWriter.apply(keyspace, table)
19
+ end
20
+
21
+ def alter_table(name, &block)
22
+ updater = TableUpdater.apply(keyspace, name) do |updater|
23
+ UpdateTableDSL.apply(updater, &block)
24
+ end
25
+ end
26
+
27
+ def truncate_table(name)
28
+ keyspace.execute("TRUNCATE #{name}")
29
+ end
30
+
31
+ def drop_table(name)
32
+ keyspace.execute("DROP TABLE #{name}")
33
+ end
34
+
35
+ def sync_table(name, &block)
36
+ existing = read_table(name)
37
+ updated = Table.new(name)
38
+ CreateTableDSL.apply(updated, &block)
39
+ TableSynchronizer.apply(keyspace, existing, updated)
40
+ end
41
+ alias_method :synchronize_table, :sync_table
42
+
43
+ protected
44
+ attr_reader :keyspace
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,120 @@
1
+ require 'stringio'
2
+
3
+ module Cequel
4
+
5
+ module Schema
6
+
7
+ class Table
8
+
9
+ attr_reader :name,
10
+ :columns,
11
+ :partition_keys,
12
+ :clustering_columns,
13
+ :data_columns,
14
+ :properties
15
+ attr_writer :compact_storage
16
+
17
+ def initialize(name)
18
+ @name = name
19
+ @partition_keys, @clustering_columns, @data_columns = [], [], []
20
+ @columns, @columns_by_name = [], {}
21
+ @properties = ActiveSupport::HashWithIndifferentAccess.new
22
+ end
23
+
24
+ def add_key(name, type, clustering_order = nil)
25
+ if @partition_keys.empty?
26
+ unless clustering_order.nil?
27
+ raise ArgumentError,
28
+ "Can't set clustering order for partition key #{name}"
29
+ end
30
+ add_partition_key(name, type)
31
+ else
32
+ add_clustering_column(name, type, clustering_order)
33
+ end
34
+ end
35
+
36
+ def add_partition_key(name, type)
37
+ column = PartitionKey.new(name, type(type))
38
+ @partition_keys << add_column(column)
39
+ end
40
+
41
+ def add_clustering_column(name, type, clustering_order = nil)
42
+ column = ClusteringColumn.new(name, type(type), clustering_order)
43
+ @clustering_columns << add_column(column)
44
+ end
45
+
46
+ def add_data_column(name, type, index_name)
47
+ index_name = :"#{@name}_#{name}_idx" if index_name == true
48
+ DataColumn.new(name, type(type), index_name).
49
+ tap { |column| @data_columns << add_column(column) }
50
+ end
51
+
52
+ def add_list(name, type)
53
+ @data_columns << add_column(List.new(name, type(type)))
54
+ end
55
+
56
+ def add_set(name, type)
57
+ @data_columns << add_column(Set.new(name, type(type)))
58
+ end
59
+
60
+ def add_map(name, key_type, value_type)
61
+ @data_columns <<
62
+ add_column(Map.new(name, type(key_type), type(value_type)))
63
+ end
64
+
65
+ def add_property(name, value)
66
+ @properties[name] = TableProperty.new(name, value)
67
+ end
68
+
69
+ def column(name)
70
+ columns_by_name[name.to_sym]
71
+ end
72
+
73
+ def key_columns
74
+ @partition_keys + @clustering_columns
75
+ end
76
+
77
+ def key_column_names
78
+ key_columns.map { |key| key.name }
79
+ end
80
+
81
+ def partition_key(name)
82
+ @partition_keys.find { |column| column.name == name }
83
+ end
84
+
85
+ def clustering_column(name)
86
+ @clustering_columns.find { |column| column.name == name }
87
+ end
88
+
89
+ def data_column(name)
90
+ name = name.to_sym
91
+ @data_columns.find { |column| column.name == name }
92
+ end
93
+
94
+ def property(name)
95
+ @properties[name].try(:value)
96
+ end
97
+
98
+ def compact_storage?
99
+ !!@compact_storage
100
+ end
101
+
102
+ protected
103
+ attr_reader :columns_by_name
104
+
105
+ private
106
+
107
+ def add_column(column)
108
+ columns << column
109
+ columns_by_name[column.name] = column
110
+ end
111
+
112
+ def type(type)
113
+ ::Cequel::Type[type]
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,67 @@
1
+ module Cequel
2
+
3
+ module Schema
4
+
5
+ class TableProperty
6
+
7
+ attr_reader :name, :value
8
+
9
+ def initialize(name, value)
10
+ @name = name
11
+ set_normalized_value(value)
12
+ end
13
+
14
+ def to_cql
15
+ if Hash === @value
16
+ map_pairs = @value.each_pair.
17
+ map { |key, value| "#{quote(key.to_s)} : #{quote(value)}" }.
18
+ join(', ')
19
+ value_cql = "{ #{map_pairs} }"
20
+ else
21
+ value_cql = quote(@value)
22
+ end
23
+ "#{@name} = #{value_cql}"
24
+ end
25
+
26
+ private
27
+
28
+ def quote(value)
29
+ CassandraCQL::Statement.quote(value)
30
+ end
31
+
32
+ def set_normalized_value(map)
33
+ return @value = map unless Hash === map
34
+ @value = {}
35
+ map.each_pair do |key, value|
36
+ key = key.to_sym
37
+ @value[key] = normalize_map_property(key, value)
38
+ end
39
+ end
40
+
41
+ def normalize_map_property(key, value)
42
+ case @name
43
+ when :compaction
44
+ case key
45
+ when :class
46
+ value.sub(/^org\.apache\.cassandra\.db\.compaction\./, '')
47
+ when :bucket_high, :bucket_low, :tombstone_threshold then value.to_f
48
+ when :max_threshold, :min_threshold, :min_sstable_size,
49
+ :sstable_size_in_mb, :tombstone_compaction_interval then value.to_i
50
+ else value.to_s
51
+ end
52
+ when :compression
53
+ case key
54
+ when :sstable_compression
55
+ value.sub(/^org\.apache\.cassandra\.io\.compress\./, '')
56
+ when :chunk_length_kb then value.to_i
57
+ when :crc_check_chance then value.to_f
58
+ else value.to_s
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end