cequel 0.5.6 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
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