@@ -553,6 +553,8 @@ def generate_files(engine, crypto_factory, min_dt=None, max_dt=None):
553553 """
554554 Create a generator of decrypted files.
555555
556+ Files are yielded in ascending order of their timestamp.
557+
556558 This function selects all current notebooks (optionally, falling within a
557559 datetime range), decrypts them, and returns a generator yielding dicts,
558560 each containing a decoded notebook and metadata including the user,
@@ -571,12 +573,8 @@ def generate_files(engine, crypto_factory, min_dt=None, max_dt=None):
571573 max_dt : datetime.datetime, optional
572574 Last modified datetime at and after which a file will be excluded.
573575 """
574- where_conds = []
575- if min_dt is not None :
576- where_conds .append (files .c .created_at >= min_dt )
577- if max_dt is not None :
578- where_conds .append (files .c .created_at < max_dt )
579- return _generate_notebooks (files , engine , where_conds , crypto_factory )
576+ return _generate_notebooks (files , files .c .created_at ,
577+ engine , crypto_factory , min_dt , max_dt )
580578
581579
582580# =======================================
@@ -736,6 +734,8 @@ def generate_checkpoints(engine, crypto_factory, min_dt=None, max_dt=None):
736734 """
737735 Create a generator of decrypted remote checkpoints.
738736
737+ Checkpoints are yielded in ascending order of their timestamp.
738+
739739 This function selects all notebook checkpoints (optionally, falling within
740740 a datetime range), decrypts them, and returns a generator yielding dicts,
741741 each containing a decoded notebook and metadata including the user,
@@ -754,38 +754,53 @@ def generate_checkpoints(engine, crypto_factory, min_dt=None, max_dt=None):
754754 max_dt : datetime.datetime, optional
755755 Last modified datetime at and after which a file will be excluded.
756756 """
757- where_conds = []
758- if min_dt is not None :
759- where_conds .append (remote_checkpoints .c .last_modified >= min_dt )
760- if max_dt is not None :
761- where_conds .append (remote_checkpoints .c .last_modified < max_dt )
762757 return _generate_notebooks (remote_checkpoints ,
763- engine , where_conds , crypto_factory )
758+ remote_checkpoints .c .last_modified ,
759+ engine , crypto_factory , min_dt , max_dt )
764760
765761
766762# ====================
767763# Files or Checkpoints
768764# ====================
769- def _generate_notebooks (table , engine , where_conds , crypto_factory ):
765+ def _generate_notebooks (table , timestamp_column ,
766+ engine , crypto_factory , min_dt , max_dt ):
770767 """
771768 See docstrings for `generate_files` and `generate_checkpoints`.
772- `where_conds` should be a list of SQLAlchemy expressions, which are used as
773- the conditions for WHERE clauses on the SELECT queries to the database.
769+
770+ Parameters
771+ ----------
772+ table : SQLAlchemy.Table
773+ Table to fetch notebooks from, `files` or `remote_checkpoints.
774+ timestamp_column : SQLAlchemy.Column
775+ `table`'s column storing timestamps, `created_at` or `last_modified`.
776+ engine : SQLAlchemy.engine
777+ Engine encapsulating database connections.
778+ crypto_factory : function[str -> Any]
779+ A function from user_id to an object providing the interface required
780+ by PostgresContentsManager.crypto. Results of this will be used for
781+ decryption of the selected notebooks.
782+ min_dt : datetime.datetime, optional
783+ Minimum last modified datetime at which a file will be included.
784+ max_dt : datetime.datetime, optional
785+ Last modified datetime at and after which a file will be excluded.
774786 """
787+ where_conds = []
788+ if min_dt is not None :
789+ where_conds .append (timestamp_column >= min_dt )
790+ if max_dt is not None :
791+ where_conds .append (timestamp_column < max_dt )
792+
775793 # Query for notebooks satisfying the conditions.
776- query = select ([table ]).order_by (table . c . user_id )
794+ query = select ([table ]).order_by (timestamp_column )
777795 for cond in where_conds :
778796 query = query .where (cond )
779797 result = engine .execute (query )
780798
781799 # Decrypt each notebook and yield the result.
782- last_user_id = None
783800 for nb_row in result :
784- # The decrypt function depends on the user, so if the user is the same
785- # then the decrypt function carries over.
786- if nb_row ['user_id' ] != last_user_id :
787- decrypt_func = crypto_factory (nb_row ['user_id' ]).decrypt
788- last_user_id = nb_row ['user_id' ]
801+ # The decrypt function depends on the user
802+ user_id = nb_row ['user_id' ]
803+ decrypt_func = crypto_factory (user_id ).decrypt
789804
790805 nb_dict = to_dict_with_content (table .c , nb_row , decrypt_func )
791806 if table is files :
@@ -798,7 +813,7 @@ def _generate_notebooks(table, engine, where_conds, crypto_factory):
798813 # here as well.
799814 yield {
800815 'id' : nb_dict ['id' ],
801- 'user_id' : nb_dict [ ' user_id' ] ,
816+ 'user_id' : user_id ,
802817 'path' : to_api_path (nb_dict ['path' ]),
803818 'last_modified' : nb_dict ['last_modified' ],
804819 'content' : reads_base64 (nb_dict ['content' ]),
0 commit comments