|
1 | 1 | # frozen_string_literal: true
|
2 | 2 |
|
| 3 | +require "mongoid/contextual/mongo/documents_loader" |
3 | 4 | require "mongoid/contextual/atomic"
|
4 | 5 | require "mongoid/contextual/aggregable/mongo"
|
5 | 6 | require "mongoid/contextual/command"
|
@@ -37,6 +38,8 @@ class Mongo
|
37 | 38 | # @attribute [r] view The Mongo collection view.
|
38 | 39 | attr_reader :view
|
39 | 40 |
|
| 41 | + attr_reader :documents_loader |
| 42 | + |
40 | 43 | # Get the number of documents matching the query.
|
41 | 44 | #
|
42 | 45 | # @example Get the number of matching documents.
|
@@ -777,6 +780,17 @@ def third_to_last!
|
777 | 780 | third_to_last || raise_document_not_found_error
|
778 | 781 | end
|
779 | 782 |
|
| 783 | + # Schedule a task to load documents for the context. |
| 784 | + # |
| 785 | + # Depending on the Mongoid configuration, the scheduled task can be executed |
| 786 | + # immediately on the caller's thread, or can be scheduled for an |
| 787 | + # asynchronous execution. |
| 788 | + # |
| 789 | + # @api private |
| 790 | + def load_async |
| 791 | + @documents_loader ||= DocumentsLoader.new(view, klass, criteria) |
| 792 | + end |
| 793 | + |
780 | 794 | private
|
781 | 795 |
|
782 | 796 | # Update the documents for the provided method.
|
@@ -844,24 +858,29 @@ def inverse_sorting
|
844 | 858 | Hash[sort.map{|k, v| [k, -1*v]}]
|
845 | 859 | end
|
846 | 860 |
|
847 |
| - # Get the documents the context should iterate. This follows 3 rules: |
848 |
| - # |
849 |
| - # 1. If the query is cached, and we already have documents loaded, use |
850 |
| - # them. |
851 |
| - # 2. If we are eager loading, then eager load the documents and use |
852 |
| - # those. |
853 |
| - # 3. Use the query. |
854 |
| - # |
855 |
| - # @api private |
| 861 | + # Get the documents the context should iterate. |
856 | 862 | #
|
857 |
| - # @example Get the documents for iteration. |
858 |
| - # context.documents_for_iteration |
| 863 | + # If the documents have been already preloaded by `Document::Loader` |
| 864 | + # instance, they will be used. |
859 | 865 | #
|
860 | 866 | # @return [ Array<Document> | Mongo::Collection::View ] The docs to iterate.
|
| 867 | + # |
| 868 | + # @api private |
861 | 869 | def documents_for_iteration
|
862 |
| - return view unless eager_loadable? |
863 |
| - docs = view.map{ |doc| Factory.from_db(klass, doc, criteria) } |
864 |
| - eager_load(docs) |
| 870 | + if @documents_loader |
| 871 | + if @documents_loader.started? |
| 872 | + @documents_loader.value! |
| 873 | + else |
| 874 | + @documents_loader.unschedule |
| 875 | + @documents_loader.execute |
| 876 | + end |
| 877 | + else |
| 878 | + return view unless eager_loadable? |
| 879 | + docs = view.map do |doc| |
| 880 | + Factory.from_db(klass, doc, criteria) |
| 881 | + end |
| 882 | + eager_load(docs) |
| 883 | + end |
865 | 884 | end
|
866 | 885 |
|
867 | 886 | # Yield to the document.
|
|
0 commit comments