cassie 1.0.0.beta.21 → 1.0.0.beta.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cassie/statements/README.md +142 -79
- data/lib/cassie/statements/execution/consistency.rb +14 -4
- data/lib/cassie/version.rb +3 -0
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 535c984598050fbd5ac382820afbc887b1fd57f5
|
4
|
+
data.tar.gz: 7f1a97fc63a2a53b4947c5f2e0ef43bcdfb594a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e627d882bdd46544ccd753fd5b215c6fbb02d913311e3e982b3e4451039b209420d030fcd2fbd0de08bf1dd8da56a56edc74f7b867318381c1296fd392f87df9
|
7
|
+
data.tar.gz: 7f3eed69154aad5ed58fb1463274977462335deaa605fdec9afda5a223f7b213072ac8f1faf76a17a545e5a0539bab46325604fe9155faa0402dc9bf1afa061c
|
@@ -96,11 +96,11 @@ Cassie provides 3 base classes for these 3 kinds of queries. Subclass `Cassie::D
|
|
96
96
|
* Adds DSL for `insert_into`, `update`, and `delete_from` statement types
|
97
97
|
* Adds support for automatically mapping values for assignments from a domain object
|
98
98
|
|
99
|
-
##### `Query`
|
99
|
+
##### `Cassie::Query`
|
100
100
|
Includes core functionality for prepared statement execution.
|
101
101
|
|
102
102
|
* Adds DSL for `select_from` statement type
|
103
|
-
* Adds `fetch` and `fetch_first` methods for executing and getting results
|
103
|
+
* Adds `fetch` and `fetch_first` methods for executing and getting results with a single method call
|
104
104
|
* Adds support for deserializing domain objects from Cassandra rows
|
105
105
|
* Adds support for paging through results with cursors
|
106
106
|
* Adds support for fetching large data sets in memory-efficient batches
|
@@ -119,7 +119,7 @@ Defining a CQL relation (the `where`) in a cassie query class creates a setter a
|
|
119
119
|
```ruby
|
120
120
|
query.user_id = 123
|
121
121
|
query.fetch
|
122
|
-
|
122
|
+
#=> [#<Struct user_id=123, id="some post id">]
|
123
123
|
```
|
124
124
|
|
125
125
|
<pre><b>
|
@@ -141,7 +141,7 @@ end
|
|
141
141
|
```ruby
|
142
142
|
query.author = User.new(id: 123)
|
143
143
|
query.fetch
|
144
|
-
|
144
|
+
#=> [#<Struct user_id=123, id="some post id">]
|
145
145
|
```
|
146
146
|
|
147
147
|
<pre><b>
|
@@ -159,7 +159,7 @@ where :user_id, :eq, value: :author_id
|
|
159
159
|
```ruby
|
160
160
|
query.author_id = 123
|
161
161
|
query.fetch
|
162
|
-
|
162
|
+
#=> [#<Struct user_id=123, id="some post id">]
|
163
163
|
```
|
164
164
|
|
165
165
|
<pre><b>
|
@@ -181,43 +181,6 @@ Relations can be conditionally evaluated:
|
|
181
181
|
This can be overdone; it's recommended that one query class be in charge of one kind of query. Avoid query classes that can do too much!
|
182
182
|
|
183
183
|
|
184
|
-
#### Column Selection (`select`)
|
185
|
-
|
186
|
-
```ruby
|
187
|
-
select_from :posts_by_author do |t|
|
188
|
-
t.select :post_id
|
189
|
-
t.select writetime(:post_id)
|
190
|
-
end
|
191
|
-
```
|
192
|
-
which is the same as
|
193
|
-
```ruby
|
194
|
-
select_from :posts_by_author
|
195
|
-
|
196
|
-
select :post_id
|
197
|
-
select writetime(:post_id)
|
198
|
-
```
|
199
|
-
|
200
|
-
`count`, `write_time` (also aliased as `writetime`), and `ttl` selector helpers are available.
|
201
|
-
|
202
|
-
```ruby
|
203
|
-
select_from :posts_by_author
|
204
|
-
|
205
|
-
select count
|
206
|
-
```
|
207
|
-
```
|
208
|
-
=> SELECT COUNT(*) FROM posts_by_author;
|
209
|
-
```
|
210
|
-
```ruby
|
211
|
-
select_from :posts_by_author
|
212
|
-
|
213
|
-
select :id
|
214
|
-
select ttl(:popular)
|
215
|
-
select writetime(:popular), as: :created_at
|
216
|
-
```
|
217
|
-
```
|
218
|
-
=> SELECT id, TTL(popular), WRITETIME(popular) AS created_at FROM posts_by_author;
|
219
|
-
```
|
220
|
-
|
221
184
|
#### Values and Assignments (`set`)
|
222
185
|
|
223
186
|
Set values (for inserts) and assignments (for updates) with the same `set` method. Similar to relations defined with `where`, assignments provide simple getters and setters.
|
@@ -246,7 +209,7 @@ end
|
|
246
209
|
query = UpdateUserQuery.new(id: current_user.id)
|
247
210
|
query.username = 'eprothro'
|
248
211
|
query.execute
|
249
|
-
|
212
|
+
#=> true
|
250
213
|
```
|
251
214
|
|
252
215
|
Mapping assignemtnt values from a domain object is supported.
|
@@ -270,7 +233,7 @@ This allows a domain object to be set for the modification object and have assig
|
|
270
233
|
|
271
234
|
```ruby
|
272
235
|
user
|
273
|
-
|
236
|
+
#=> #<User:0x007ff8895ce660 @id=6539, @phone="+15555555555", @email="etp@example.com", @address=nil, @username= "etp">
|
274
237
|
UpdateUserQuery.new(user: user).execute
|
275
238
|
```
|
276
239
|
|
@@ -300,7 +263,7 @@ class UpdateUserQuery < Cassandra::Modification
|
|
300
263
|
```
|
301
264
|
```ruby
|
302
265
|
user
|
303
|
-
|
266
|
+
#=> #<User:0x007ff8895ce660 @id=6539, @phone="+15555555555", @email="etp@example.com", @address=nil, @username= "ETP">
|
304
267
|
UpdateUserQuery.new(user: user).execute
|
305
268
|
```
|
306
269
|
|
@@ -336,20 +299,79 @@ end
|
|
336
299
|
|
337
300
|
> Note: The `term` option should be used with care. Using it innapropriately could result in inefficient use of prepared statements, and/or leave you potentially vulnerable to injection attacks.
|
338
301
|
|
302
|
+
|
303
|
+
#### Column Selection (`select`)
|
304
|
+
|
305
|
+
By default, all columns will be selected (e.g. '*'). Specify a column for selection with `select`.
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
select_from :posts_by_author do |t|
|
309
|
+
t.select :post_id
|
310
|
+
t.select writetime(:post_id)
|
311
|
+
end
|
312
|
+
```
|
313
|
+
which is the same as
|
314
|
+
```ruby
|
315
|
+
select_from :posts_by_author
|
316
|
+
|
317
|
+
select :post_id
|
318
|
+
select writetime(:post_id)
|
319
|
+
```
|
320
|
+
|
321
|
+
`count`, `write_time` (also aliased as `writetime`), and `ttl` selector helpers are available.
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
select_from :posts_by_author
|
325
|
+
|
326
|
+
select count
|
327
|
+
```
|
328
|
+
```
|
329
|
+
#=> SELECT COUNT(*) FROM posts_by_author;
|
330
|
+
```
|
331
|
+
|
332
|
+
Aliasing is supported with the `as` option.
|
333
|
+
```ruby
|
334
|
+
select_from :posts_by_author
|
335
|
+
|
336
|
+
select :id
|
337
|
+
select ttl(:popular)
|
338
|
+
select writetime(:popular), as: :created_at
|
339
|
+
```
|
340
|
+
```
|
341
|
+
#=> SELECT id, TTL(popular), WRITETIME(popular) AS created_at FROM posts_by_author;
|
342
|
+
```
|
343
|
+
Arbitrary strings are supported as well in case the DSL gets in the way.
|
344
|
+
|
345
|
+
```ruby
|
346
|
+
select_from :posts_by_author
|
347
|
+
|
348
|
+
select 'cowboy, coder'
|
349
|
+
```
|
350
|
+
```
|
351
|
+
#=> SELECT cowboy, coder FROM posts_by_author;
|
352
|
+
```
|
353
|
+
|
339
354
|
#### Consistency configuration
|
340
355
|
|
341
356
|
The [consistency level](http://datastax.github.io/ruby-driver/v2.1.6/api/cassandra/#consistencies-constant) for a query is determined by your `Cassie::configuration` by default, falling to back to the `Cassandra` default if none is given.
|
342
357
|
|
343
358
|
```ruby
|
344
359
|
Cassie.configuration[:consistency]
|
345
|
-
|
360
|
+
#=> nil
|
346
361
|
|
347
362
|
Cassie.cluster.instance_variable_get(:@execution_options).consistency
|
348
|
-
|
363
|
+
#=> :one
|
349
364
|
```
|
350
365
|
|
351
|
-
Cassie queries allow for a consistency level defined on the object, subclass,
|
366
|
+
Cassie queries allow for a consistency level to be defined on the object, subclass, base class, and global levels. If none is found, it will default to the `cluster` default when the query is executed.
|
352
367
|
|
368
|
+
Object writer:
|
369
|
+
```ruby
|
370
|
+
query = MyQuery.new
|
371
|
+
query.consistency = :all
|
372
|
+
query.execute
|
373
|
+
```
|
374
|
+
Override Object reader:
|
353
375
|
```ruby
|
354
376
|
select_from :posts_by_author_category
|
355
377
|
|
@@ -370,6 +392,7 @@ Cassie queries allow for a consistency level defined on the object, subclass, th
|
|
370
392
|
end
|
371
393
|
```
|
372
394
|
|
395
|
+
Class writer
|
373
396
|
```ruby
|
374
397
|
select_from :posts_by_author_category
|
375
398
|
|
@@ -379,45 +402,85 @@ Cassie queries allow for a consistency level defined on the object, subclass, th
|
|
379
402
|
consistency :quorum
|
380
403
|
```
|
381
404
|
|
405
|
+
Cassie query classes
|
382
406
|
```ruby
|
383
407
|
# lib/tasks/interesting_task.rake
|
384
408
|
require_relative "interesting_worker"
|
385
409
|
|
386
410
|
task :interesting_task do
|
387
|
-
|
411
|
+
Cassie::Modification.consistency = :all
|
388
412
|
|
389
413
|
InterestingWorker.new.perform
|
390
414
|
end
|
391
415
|
```
|
392
416
|
|
417
|
+
Cassie global default
|
418
|
+
```ruby
|
419
|
+
# lib/tasks/interesting_task.rake
|
420
|
+
require_relative "interesting_worker"
|
421
|
+
|
422
|
+
task :interesting_task do
|
423
|
+
Cassie::Statements.default_consistency = :all
|
424
|
+
|
425
|
+
InterestingWorker.new.perform
|
426
|
+
end
|
427
|
+
```
|
428
|
+
|
429
|
+
#### Execution and Result
|
430
|
+
|
431
|
+
Executing a `Cassie::Query` populates the `result` attribute.
|
432
|
+
|
433
|
+
```ruby
|
434
|
+
query.execute
|
435
|
+
# => true
|
436
|
+
query.result.class
|
437
|
+
# => Cassie::Statements::Results::QueryResult
|
438
|
+
```
|
439
|
+
|
440
|
+
The result lazily enumerates domain objects
|
441
|
+
```ruby
|
442
|
+
query.execute
|
443
|
+
#=> true
|
444
|
+
query.result.each
|
445
|
+
#=> #<[#< Struct id=:123, username=:eprothro >]>
|
446
|
+
```
|
447
|
+
|
448
|
+
The result also delegates to the `Cassandra::Result`.
|
449
|
+
```ruby
|
450
|
+
query.result.execution_info
|
451
|
+
#=> #<Cassandra::Execution::Info:0x007fb404b51390 @payload=nil, @warnings=nil, @keyspace="cassie_test", @statement=#<Cassandra::Statements::Bound:0x3fda0258dee8 @cql="SELECT * FROM users_by_username LIMIT 500;" @params=[]>, @options=#<Cassandra::Execution::Options:0x007fb404b1b880 @consistency=:local_one, @page_size=10000, @trace=false, @timeout=12, @serial_consistency=nil, @arguments=[], @type_hints=[], @paging_state=nil, @idempotent=false, @payload=nil>, @hosts=[#<Cassandra::Host:0x3fda02541390 @ip=127.0.0.1>], @consistency=:local_one, @retries=0, @trace=nil>
|
452
|
+
query.result.rows
|
453
|
+
#=> #<Enumerator: [{"id"=>123, "username"=>"eprothro"}]>
|
454
|
+
```
|
455
|
+
|
393
456
|
#### Finders
|
394
457
|
|
395
458
|
To avoid confusion with ruby `Enumerable#find` and Rails' specific `find` functionality, Cassie::Query opts to use `fetch` and explict `fetch_first` or `fetch_first!` methods.
|
396
459
|
|
397
460
|
##### `fetch`
|
398
461
|
|
399
|
-
|
462
|
+
Calls setters for any opts passed, executes the query, and returns the result.
|
400
463
|
|
401
|
-
```
|
464
|
+
```ruby
|
402
465
|
UsersByResourceQuery.new.fetch(resource: some_resource).to_a
|
403
|
-
|
466
|
+
#=> [#<User id=:123, username=:eprothro>, #<User id=:456, username=:tenderlove>]
|
404
467
|
```
|
405
468
|
|
406
469
|
##### `fetch_first` and `fetch_first!`
|
407
470
|
|
408
|
-
|
471
|
+
Temporarily limits the query to 1 result; returns a single domain object. Bang version raises if no row is found.
|
409
472
|
|
410
|
-
```
|
411
|
-
UsersByUsernameQuery.new.fetch_first(username: "eprothro")
|
412
|
-
|
473
|
+
```ruby
|
474
|
+
UsersByUsernameQuery.new.fetch_first(username: "eprothro")
|
475
|
+
#=> #<User id=:123, username=:eprothro>
|
413
476
|
```
|
414
477
|
|
415
|
-
```
|
478
|
+
```ruby
|
416
479
|
UsersByUsernameQuery.new.fetch_first(username: "ActiveRecord")
|
417
|
-
|
480
|
+
#=> nil
|
418
481
|
```
|
419
482
|
|
420
|
-
```
|
483
|
+
```ruby
|
421
484
|
UsersByUsernameQuery.new.fetch_first!(username: "active record").username
|
422
485
|
Cassie::Statements::RecordNotFound: CQL row does not exist
|
423
486
|
```
|
@@ -428,19 +491,19 @@ Similar to [Rails BatchedFetching](http://guides.rubyonrails.org/v4.2/active_rec
|
|
428
491
|
|
429
492
|
###### `fetch_each`
|
430
493
|
|
431
|
-
```
|
494
|
+
```ruby
|
432
495
|
UsersQuery.new.fetch_each do |user|
|
433
496
|
# only 1000 queried and loaded at a time
|
434
497
|
end
|
435
498
|
```
|
436
499
|
|
437
|
-
```
|
500
|
+
```ruby
|
438
501
|
UsersQuery.new.fetch_each(batch_size: 500) do |user|
|
439
502
|
# only 500 queried and loaded at a time
|
440
503
|
end
|
441
504
|
```
|
442
505
|
|
443
|
-
```
|
506
|
+
```ruby
|
444
507
|
UsersQuery.new.fetch_each.with_index do |user, index|
|
445
508
|
# Enumerator chaining without a block
|
446
509
|
end
|
@@ -448,19 +511,19 @@ end
|
|
448
511
|
|
449
512
|
###### `fetch_in_batches`
|
450
513
|
|
451
|
-
```
|
514
|
+
```ruby
|
452
515
|
UsersQuery.new.fetch_in_batches do |users_array|
|
453
516
|
# only 1000 queried and at a time
|
454
517
|
end
|
455
518
|
```
|
456
519
|
|
457
|
-
```
|
520
|
+
```ruby
|
458
521
|
UsersQuery.new.fetch_in_batches(batch_size: 500) do |users_array|
|
459
522
|
# only 500 queried and at a time
|
460
523
|
end
|
461
524
|
```
|
462
525
|
|
463
|
-
```
|
526
|
+
```ruby
|
464
527
|
UsersQuery.new.fetch_in_batches.with_index do |group, index|
|
465
528
|
# Enumerator chaining without a block
|
466
529
|
end
|
@@ -468,19 +531,19 @@ end
|
|
468
531
|
|
469
532
|
#### Deserialization
|
470
533
|
|
471
|
-
For
|
534
|
+
For `Cassie::Query` classes, records are deserialized as anonymous structs by default. Each field returned from the database will have an accessor.
|
472
535
|
|
473
536
|
```ruby
|
474
537
|
UsersByUsernameQuery.new.fetch(username: "eprothro")
|
475
538
|
#=> [#<Struct id=:123, username=:eprothro>]
|
476
539
|
|
477
|
-
UsersByUsernameQuery.new.fetch_first(username: "eprothro").username
|
478
|
-
|
540
|
+
UsersByUsernameQuery.new.fetch_first!(username: "eprothro").username
|
541
|
+
#=> "eprothro"
|
479
542
|
```
|
480
543
|
|
481
544
|
Most applications will want to override `build_result` to construct more useful domain objects
|
482
545
|
|
483
|
-
```
|
546
|
+
```ruby
|
484
547
|
class UsersByUsernameQuery < Cassie::Query
|
485
548
|
|
486
549
|
select_from :users_by_username
|
@@ -495,10 +558,10 @@ end
|
|
495
558
|
|
496
559
|
```ruby
|
497
560
|
UsersByUsernameQuery.new.fetch_first(username: "eprothro")
|
498
|
-
|
561
|
+
#=> #<User:0x007fedec219cd8 @id=123, @username="eprothro">
|
499
562
|
```
|
500
563
|
|
501
|
-
`build_results` may be overridden as well to define
|
564
|
+
`build_results` may be overridden as well to define custom definition of the enumeration of rows returned from Cassandra.
|
502
565
|
|
503
566
|
#### Cursored paging
|
504
567
|
|
@@ -614,14 +677,14 @@ class RecordsByOwnerQuery < Cassie::Query
|
|
614
677
|
end
|
615
678
|
end
|
616
679
|
```
|
617
|
-
```
|
680
|
+
```ruby
|
618
681
|
RecordsByOwnerQuery.new(owner: owner, min_record: 99,990).fetch.map(&:record)
|
619
682
|
(2.9ms) SELECT * FROM records_by_owner WHERE owner_id = ? AND bucket = ? AND record >= ? LIMIT 100; [123, 0, 99990]
|
620
683
|
(2.9ms) SELECT * FROM records_by_owner WHERE owner_id = ? AND bucket = ? AND record >= ? LIMIT 100; [123, 1, 99990]
|
621
|
-
|
684
|
+
#=> [99990, 99991, ..., 100089, 100090]
|
622
685
|
```
|
623
686
|
|
624
|
-
The first partition queried is defined within the query class (bucket 0). The linking policy handles recognizing the end of the first partition has been reached, issuing the second query
|
687
|
+
The first partition queried is defined within the query class (bucket 0). The linking policy handles recognizing the end of the first partition has been reached, issuing the second query for the second partition (bucket 1), and combining the results from both queries.
|
625
688
|
|
626
689
|
By default, this works for ascending and descending orderings when paging in the same order as the clustering order; it also works with cursoring.
|
627
690
|
|
@@ -629,9 +692,9 @@ Custom policies can be defined by setting `Query.partition_linker` for more comp
|
|
629
692
|
|
630
693
|
#### Prepared statements
|
631
694
|
|
632
|
-
A `Cassie::Query` will use prepared statements by default, cacheing prepared statements across all
|
695
|
+
A `Cassie::Query` will use prepared statements by default, cacheing prepared statements across all `Query`, `Modification`, and `Definition` objects, keyed by the unbound CQL string.
|
633
696
|
|
634
|
-
To
|
697
|
+
To disable prepared statements for a particular query, disable the `.prepare` class option.
|
635
698
|
|
636
699
|
```ruby
|
637
700
|
class MySpecialQuery < Cassie::Query
|
@@ -657,9 +720,9 @@ set_1 = query.fetch([1, 2, 3])
|
|
657
720
|
set_2 = query.fetch([7, 8, 9, 10, 11, 12])
|
658
721
|
```
|
659
722
|
|
660
|
-
####
|
723
|
+
#### Non-positional (unbound) statements
|
661
724
|
|
662
|
-
Cassie Query features are built around bound statements. However, overriding `#statement`, returning something that a `Cassandra::Session` can execute an unbound statement.
|
725
|
+
Cassie Query features are built around using bound statements with positional arguments. However, overriding `#statement`, returning something that a `Cassandra::Session` can execute, will result in an unbound, unprepared statement.
|
663
726
|
|
664
727
|
```ruby
|
665
728
|
class MySafeQuery < Cassie::Definition
|
@@ -669,7 +732,7 @@ class MySafeQuery < Cassie::Definition
|
|
669
732
|
end
|
670
733
|
```
|
671
734
|
|
672
|
-
> Note: unbound queries
|
735
|
+
> Note: unbound queries can be vulnerable to injection attacks. Be careful.
|
673
736
|
|
674
737
|
#### Logging
|
675
738
|
|
@@ -1,5 +1,14 @@
|
|
1
|
-
module Cassie::Statements
|
2
|
-
|
1
|
+
module Cassie::Statements
|
2
|
+
def self.default_consistency
|
3
|
+
return @default_consistency if defined?(@default_consistency)
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.default_consistency=(val)
|
8
|
+
@default_consistency = val
|
9
|
+
end
|
10
|
+
|
11
|
+
module Execution::Consistency
|
3
12
|
extend ActiveSupport::Concern
|
4
13
|
|
5
14
|
included do
|
@@ -8,7 +17,7 @@ module Cassie::Statements::Execution
|
|
8
17
|
|
9
18
|
module ClassMethods
|
10
19
|
def inherited(subclass)
|
11
|
-
subclass.consistency = consistency
|
20
|
+
subclass.consistency = consistency if defined?(@consistency)
|
12
21
|
super
|
13
22
|
end
|
14
23
|
|
@@ -18,7 +27,8 @@ module Cassie::Statements::Execution
|
|
18
27
|
|
19
28
|
def consistency(val=:get)
|
20
29
|
if val == :get
|
21
|
-
@consistency if defined?(@consistency)
|
30
|
+
return @consistency if defined?(@consistency)
|
31
|
+
Cassie::Statements.default_consistency
|
22
32
|
else
|
23
33
|
self.consistency = val
|
24
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
4
|
+
version: 1.0.0.beta.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Prothro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cassandra-driver
|
@@ -58,6 +58,34 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '3.4'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rake
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '11.3'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '11.3'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: gem-release
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.7.4
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.7.4
|
61
89
|
- !ruby/object:Gem::Dependency
|
62
90
|
name: byebug
|
63
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +218,7 @@ files:
|
|
190
218
|
- lib/cassie/testing/fake/result.rb
|
191
219
|
- lib/cassie/testing/fake/session.rb
|
192
220
|
- lib/cassie/testing/fake/session_methods.rb
|
221
|
+
- lib/cassie/version.rb
|
193
222
|
homepage: https://github.com/eprothro/cassie
|
194
223
|
licenses:
|
195
224
|
- MIT
|