Class: Tina4::DocStore::SqliteCollection
- Inherits:
-
Object
- Object
- Tina4::DocStore::SqliteCollection
- Defined in:
- lib/tina4/docstore.rb
Overview
A SQLite-backed collection exposing the everyday Mongo API.
Instance Method Summary collapse
- #count_documents(filter = nil) ⇒ Object
- #delete_many(filter) ⇒ Object
-
#delete_one(filter) ⇒ Object
-- deletes --.
- #distinct(key, filter = nil) ⇒ Object
- #drop ⇒ Object
- #estimated_document_count ⇒ Object
-
#find(filter = nil, projection = nil) ⇒ Object
-- reads --.
-
#find_one(filter = nil, projection = nil) ⇒ Object
The uniform Tina4 spelling, ADDITIVE to find(filter).first (ADR-0035).
-
#initialize(conn, name) ⇒ SqliteCollection
constructor
A new instance of SqliteCollection.
- #insert_many(documents) ⇒ Object
-
#insert_one(document) ⇒ Object
-- writes --.
- #replace_one(filter, replacement, upsert: false) ⇒ Object
- #update_many(filter, update, upsert: false) ⇒ Object
-
#update_one(filter, update, upsert: false) ⇒ Object
-- updates (filter pushed to SQL; mutation applied per matched doc) --.
Constructor Details
#initialize(conn, name) ⇒ SqliteCollection
Returns a new instance of SqliteCollection.
557 558 559 560 561 562 563 564 565 566 |
# File 'lib/tina4/docstore.rb', line 557 def initialize(conn, name) @connection = conn @name = name.to_s raise ArgumentError, "DocStore: invalid collection name #{name.inspect}" unless @name.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/) @quoted_name = "\"#{@name}\"" @connection.execute( "CREATE TABLE IF NOT EXISTS #{@quoted_name} (_id TEXT PRIMARY KEY, doc TEXT NOT NULL)" ) end |
Instance Method Details
#count_documents(filter = nil) ⇒ Object
610 611 612 613 614 |
# File 'lib/tina4/docstore.rb', line 610 def count_documents(filter = nil) where, params = DocStore.compile_filter(filter || {}) row = @connection.execute("SELECT count(*) AS c FROM #{@quoted_name} WHERE #{where}", params).first scalar(row).to_i end |
#delete_many(filter) ⇒ Object
687 688 689 690 691 692 |
# File 'lib/tina4/docstore.rb', line 687 def delete_many(filter) where, params = DocStore.compile_filter(filter || {}) before = count_documents(filter) @connection.execute("DELETE FROM #{@quoted_name} WHERE #{where}", params) DeleteResult.new(before) end |
#delete_one(filter) ⇒ Object
-- deletes --
679 680 681 682 683 684 685 |
# File 'lib/tina4/docstore.rb', line 679 def delete_one(filter) rows = matching_rows(filter, limit: 1) return DeleteResult.new(0) if rows.empty? @connection.execute("DELETE FROM #{@quoted_name} WHERE _id = ?", [rows.first.first]) DeleteResult.new(1) end |
#distinct(key, filter = nil) ⇒ Object
621 622 623 624 625 626 627 628 |
# File 'lib/tina4/docstore.rb', line 621 def distinct(key, filter = nil) seen = [] find(filter).each do |doc| v = doc[key.to_s] seen << v unless seen.include?(v) end seen end |
#drop ⇒ Object
694 695 696 |
# File 'lib/tina4/docstore.rb', line 694 def drop @connection.execute("DROP TABLE IF EXISTS #{@quoted_name}") end |
#estimated_document_count ⇒ Object
616 617 618 619 |
# File 'lib/tina4/docstore.rb', line 616 def estimated_document_count row = @connection.execute("SELECT count(*) AS c FROM #{@quoted_name}").first scalar(row).to_i end |
#find(filter = nil, projection = nil) ⇒ Object
-- reads --
594 595 596 597 |
# File 'lib/tina4/docstore.rb', line 594 def find(filter = nil, projection = nil) where, params = DocStore.compile_filter(filter || {}) Cursor.new(@connection, @quoted_name, where, params, projection) end |
#find_one(filter = nil, projection = nil) ⇒ Object
The uniform Tina4 spelling, ADDITIVE to find(filter).first (ADR-0035).
Mongo::Collection has no find_one, which is why ADR-0025 corollary 1 deleted this. ADR-0035 amends the means, not the goal: MongoCollection supplies find_one on the driver side, so the method now exists with the same meaning on BOTH halves of the swap. The signature is pymongo's, which is what the Python master already ships.
606 607 608 |
# File 'lib/tina4/docstore.rb', line 606 def find_one(filter = nil, projection = nil) find(filter, projection).first end |
#insert_many(documents) ⇒ Object
579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'lib/tina4/docstore.rb', line 579 def insert_many(documents) ids = [] documents.each do |document| doc = stringify(document) doc["_id"] = ObjectId.new unless doc.key?("_id") ids << doc["_id"] @connection.execute( "INSERT INTO #{@quoted_name} (_id, doc) VALUES (?, ?)", [DocStore.id_key(doc["_id"]), DocStore.dump_doc(doc)] ) end InsertManyResult.new(ids) end |
#insert_one(document) ⇒ Object
-- writes --
569 570 571 572 573 574 575 576 577 |
# File 'lib/tina4/docstore.rb', line 569 def insert_one(document) doc = stringify(document) doc["_id"] = ObjectId.new unless doc.key?("_id") @connection.execute( "INSERT INTO #{@quoted_name} (_id, doc) VALUES (?, ?)", [DocStore.id_key(doc["_id"]), DocStore.dump_doc(doc)] ) InsertOneResult.new(doc["_id"]) end |
#replace_one(filter, replacement, upsert: false) ⇒ Object
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
# File 'lib/tina4/docstore.rb', line 660 def replace_one(filter, replacement, upsert: false) rows = matching_rows(filter, limit: 1) if rows.empty? if upsert doc = stringify(replacement) doc["_id"] = ObjectId.new unless doc.key?("_id") insert_one(doc) return UpdateResult.new(0, 0, doc["_id"]) end return UpdateResult.new(0, 0, nil) end old_id, doc_text = rows.first doc = stringify(replacement) doc["_id"] = DocStore.decode_value(JSON.parse(doc_text))["_id"] unless doc.key?("_id") write_back(old_id, doc) UpdateResult.new(1, 1, nil) end |
#update_many(filter, update, upsert: false) ⇒ Object
645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/tina4/docstore.rb', line 645 def update_many(filter, update, upsert: false) rows = matching_rows(filter) return do_upsert(filter, update) if rows.empty? && upsert matched = 0 modified = 0 rows.each do |old_id, doc_text| matched += 1 doc = DocStore.decode_value(JSON.parse(doc_text)) new_doc = DocStore.apply_update(doc, update) modified += 1 if write_back(old_id, new_doc) end UpdateResult.new(matched, modified, nil) end |
#update_one(filter, update, upsert: false) ⇒ Object
-- updates (filter pushed to SQL; mutation applied per matched doc) --
631 632 633 634 635 636 637 638 639 640 641 642 643 |
# File 'lib/tina4/docstore.rb', line 631 def update_one(filter, update, upsert: false) rows = matching_rows(filter, limit: 1) if rows.empty? return do_upsert(filter, update) if upsert return UpdateResult.new(0, 0, nil) end old_id, doc_text = rows.first doc = DocStore.decode_value(JSON.parse(doc_text)) new_doc = DocStore.apply_update(doc, update) modified = write_back(old_id, new_doc) UpdateResult.new(1, modified ? 1 : 0, nil) end |