@@ -28,6 +28,7 @@ typedef _ArgumentContext = ({
2828/// should be included in a generated database or dao class.
2929class QueryWriter {
3030 final Scope scope;
31+ final Map <CapturedVariable , String > _outerVariables = {};
3132
3233 late final ExplicitAliasTransformer _transformer;
3334 final TextEmitter _emitter;
@@ -40,6 +41,8 @@ class QueryWriter {
4041
4142 QueryWriter (this .scope) : _emitter = scope.leaf ();
4243
44+ QueryWriter ._existingEmitter (this .scope, this ._emitter);
45+
4346 void write (SqlQuery query) {
4447 // Note that writing queries can have a result set if they use a RETURNING
4548 // clause.
@@ -88,9 +91,10 @@ class QueryWriter {
8891
8992 /// Writes the function literal that turns a "QueryRow" into the desired
9093 /// custom return type of a query.
91- void _writeMappingLambda (InferredResultSet resultSet, QueryRowType rowClass) {
94+ void _writeMappingLambda (InferredResultSet resultSet,
95+ NestedQueriesContainer ? nestedQueries, QueryRowType rowClass) {
9296 if (drift3) {
93- return _Drift3MappingCodeWriter (this )
97+ return _Drift3MappingCodeWriter (this , nestedQueries )
9498 .write (_emitter, resultSet, rowClass);
9599 }
96100
@@ -317,17 +321,20 @@ class QueryWriter {
317321 [QueryRowType ? resultType]) {
318322 final resultSet = select.resultSet;
319323 resultType ?? = select.queryRowType (options);
324+ final needsAsyncMapping = resultType.requiresAsynchronousContext (options);
320325
321326 if (drift3) {
327+ final methodName =
328+ needsAsyncMapping ? 'customSelectMappedAsync' : 'customSelectMapped' ;
322329 _emitter
323- ..write (' customSelectMapped <' )
330+ ..write (' $ methodName <' )
324331 ..writeDart (resultType.rowType)
325332 ..write ('>(query: ${_queryCode (select )},' );
326333 _writeVariables (select);
327334 _emitter.write (', ' );
328335 _writeReadsFrom (select);
329336 _emitter.write (', createMapper: ' );
330- _writeMappingLambda (resultSet, resultType);
337+ _writeMappingLambda (resultSet, select.nestedContainer, resultType);
331338 _emitter.write (')' );
332339 return ;
333340 }
@@ -337,13 +344,13 @@ class QueryWriter {
337344 _buffer.write (', ' );
338345 _writeReadsFrom (select);
339346
340- if (resultType. requiresAsynchronousContext (options) ) {
347+ if (needsAsyncMapping ) {
341348 _buffer.write (').asyncMap(' );
342349 } else {
343350 _buffer.write (').map(' );
344351 }
345352
346- _writeMappingLambda (resultSet, resultType);
353+ _writeMappingLambda (resultSet, select.nestedContainer, resultType);
347354 _buffer.write (')' );
348355 }
349356
@@ -374,7 +381,7 @@ class QueryWriter {
374381 if (drift3) {
375382 _buffer.writeln (').then((rows) {' );
376383
377- final mappingWriter = _Drift3MappingCodeWriter (this )
384+ final mappingWriter = _Drift3MappingCodeWriter (this , null )
378385 .._writeArgumentExpression (
379386 rowType, resultSet, (isNullable: false , sqlPrefix: null ));
380387 _buffer
@@ -398,11 +405,11 @@ class QueryWriter {
398405
399406 if (rowType.requiresAsynchronousContext (options)) {
400407 _buffer.write ('Future.wait(rows.map(' );
401- _writeMappingLambda (resultSet, rowType);
408+ _writeMappingLambda (resultSet, null , rowType);
402409 _buffer.write ('))' );
403410 } else {
404411 _buffer.write ('rows.map(' );
405- _writeMappingLambda (resultSet, rowType);
412+ _writeMappingLambda (resultSet, null , rowType);
406413 _buffer.write (').toList()' );
407414 }
408415 _buffer.write (');\n }' );
@@ -545,7 +552,7 @@ class QueryWriter {
545552 }
546553
547554 void _writeVariables (SqlQuery query) {
548- _ExpandedVariableWriter (query, _emitter ).writeVariables ();
555+ _ExpandedVariableWriter (query, this ).writeVariables ();
549556 }
550557
551558 /// Returns a Dart string literal representing the query after variables have
@@ -640,6 +647,7 @@ String readConverter(TextEmitter emitter, AppliedTypeConverter converter) {
640647/// query.
641648class _Drift3MappingCodeWriter {
642649 final QueryWriter _writer;
650+ final NestedQueriesContainer ? nestedQueries;
643651
644652 final StringBuffer _outerSetup = StringBuffer ();
645653 final StringBuffer _innerMapper = StringBuffer ();
@@ -649,7 +657,7 @@ class _Drift3MappingCodeWriter {
649657
650658 TextEmitter get _emitter => _writer._emitter;
651659
652- _Drift3MappingCodeWriter (this ._writer);
660+ _Drift3MappingCodeWriter (this ._writer, this .nestedQueries );
653661
654662 String referenceBuiltinType (DriftSqlType type) {
655663 return _obtainedTypes.putIfAbsent (type, () {
@@ -690,7 +698,10 @@ class _Drift3MappingCodeWriter {
690698 ..writeln (_outerSetup)
691699 ..write ('return (' )
692700 ..writeDriftRef ('RawRow' )
693- ..writeln (' row) => $_innerMapper ;' )
701+ ..write (' row) ' )
702+ ..write (
703+ rowClass.requiresAsynchronousContext (_writer.options) ? 'async' : '' )
704+ ..writeln ('=> $_innerMapper ;' )
694705 ..writeln ('}' );
695706 }
696707
@@ -715,12 +726,23 @@ class _Drift3MappingCodeWriter {
715726 resultSet,
716727 (sqlPrefix: prefix, isNullable: argument.nullable),
717728 );
718- case MappedNestedListQuery ():
719- _innerMapper.write ("throw 'todo'" );
720- // _innerMapper.write('await ');
721- // final query = argument.column.query;
722- // _writeCustomSelectStatement(query, argument.nestedType);
723- // _innerMapper.write('.get()');
729+ case MappedNestedListQuery (: final column):
730+ final knownVariableTypes = < CapturedVariable , String > {};
731+ if (nestedQueries? .nestedQueries[column.from] case final nested? ) {
732+ for (final variable in nested.capturedVariables.values) {
733+ if (variable.resolvedVariable case final resolved? ) {
734+ knownVariableTypes[variable] = referenceType (resolved.sqlType);
735+ }
736+ }
737+ }
738+
739+ _innerMapper.write ('await ' );
740+ final query = argument.column.query;
741+ final innerWriter = QueryWriter ._existingEmitter (
742+ _writer.scope, TextEmitter (_writer.scope, buffer: _innerMapper));
743+ innerWriter._outerVariables.addAll (knownVariableTypes);
744+ innerWriter._writeCustomSelectStatement (query, argument.nestedType);
745+ _innerMapper.write ('.get()' );
724746 case QueryRowType ():
725747 final singleValue = argument.singleValue;
726748 if (singleValue != null ) {
@@ -1007,10 +1029,12 @@ class _ExpandedDeclarationWriter {
10071029class _ExpandedVariableWriter {
10081030 final SqlQuery query;
10091031 final TextEmitter _emitter;
1032+ final QueryWriter _queryWriter;
10101033
10111034 StringBuffer get _buffer => _emitter.buffer;
10121035
1013- _ExpandedVariableWriter (this .query, this ._emitter);
1036+ _ExpandedVariableWriter (this .query, this ._queryWriter)
1037+ : _emitter = _queryWriter._emitter;
10141038
10151039 void writeVariables () {
10161040 _buffer.write ('variables: ' );
@@ -1097,6 +1121,16 @@ class _ExpandedVariableWriter {
10971121 String constructVar (String dartExpr) {
10981122 final capture = element.forCaptured;
10991123 if (capture != null ) {
1124+ if (_emitter.writer.options.drift3Preview) {
1125+ return _emitter.dartCode (AnnotatedDartCode .build ((b) {
1126+ b.addSymbol ('MappedValue' , AnnotatedDartCode .drift);
1127+ b.addText ('.raw(' );
1128+ b.addText ('${_queryWriter ._outerVariables [capture ]},' );
1129+ b.addText ('row[${capture .columnIndex }]' );
1130+ b.addText (')' );
1131+ }));
1132+ }
1133+
11001134 dartExpr = ('row.read(${asDartLiteral (capture .helperColumn )})' );
11011135 }
11021136
0 commit comments