Skip to content

Commit 03d3a68

Browse files
committed
Allow calling first() and single() multiple times as long as we're not passed the first record
1 parent d1b4737 commit 03d3a68

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

driver/src/main/java/org/neo4j/driver/internal/InternalResultCursor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ else if ( records == 0) {
173173
@Override
174174
public Record first()
175175
{
176-
if( position() > 0 )
176+
if( position() >= 1 )
177177
{
178178
throw new NoSuchRecordException( "Cannot retrieve the first record, because this result cursor has been moved already. " +
179179
"Please ensure you are not calling `first` multiple times, or are mixing it with calls " +

driver/src/main/java/org/neo4j/driver/v1/ResultCursor.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public interface ResultCursor extends RecordAccessor, Resource
9292

9393
/**
9494
* Return the first record in the stream. Fail with an exception if the stream is empty
95-
* or if this cursor has already been used to move "into" the stream.
95+
* or if this cursor has already been used to move past the first record.
9696
*
9797
* @return the first record in the stream
9898
* @throws NoSuchRecordException if there is no first record or the cursor has been used already
@@ -102,7 +102,7 @@ public interface ResultCursor extends RecordAccessor, Resource
102102

103103
/**
104104
* Return a field value from the first record in the stream. Fail with an exception if the stream is empty
105-
* or if this cursor has already been used to move "into" the stream.
105+
* or if this cursor has already been used to move past the first record.
106106
*
107107
* @param fieldName the name of the field to return from the first record in the stream
108108
* @return the specified field from the first record in the stream
@@ -113,7 +113,7 @@ public interface ResultCursor extends RecordAccessor, Resource
113113

114114
/**
115115
* Return a field value from the first record in the stream. Fail with an exception if the stream is empty
116-
* or if this cursor has already been used to move "into" the stream.
116+
* or if this cursor has already been used to move past the first record.
117117
*
118118
* @param index the index of the field to return from the first record in the stream
119119
* @return the specified field from the first record in the stream
@@ -124,7 +124,7 @@ public interface ResultCursor extends RecordAccessor, Resource
124124

125125
/**
126126
* Move to the first record and return an immutable copy of it, failing if there is not exactly
127-
* one record in the stream, or if this cursor has already been used to move "into" the stream.
127+
* one record in the stream, or if this cursor has already been used to move past the first record.
128128
*
129129
* @return the first and only record in the stream
130130
* @throws NoSuchRecordException if there is not exactly one record in the stream, or if the cursor has been used already
@@ -133,7 +133,7 @@ public interface ResultCursor extends RecordAccessor, Resource
133133

134134
/**
135135
* Move to the first record and return a field value from it, failing if there is not exactly
136-
* one record in the stream, or if this cursor has already been used to move "into" the stream.
136+
* one record in the stream, or if this cursor has already been used to move past the first record.
137137
*
138138
* @param fieldName the name of the field to return from the first and only record in the stream
139139
* @return the value of the specified field of the first and only record in the stream
@@ -143,7 +143,7 @@ public interface ResultCursor extends RecordAccessor, Resource
143143

144144
/**
145145
* Move to the first record and return a field value from it, failing if there is not exactly
146-
* one record in the stream, or if this cursor has already been used to move "into" the stream.
146+
* one record in the stream, or if this cursor has already been used to move past the first record.
147147
*
148148
* @param index the index of the field to return from the first and only record in the stream
149149
* @return the value of the specified field of the first and only record in the stream

driver/src/test/java/org/neo4j/driver/internal/InternalResultCursorTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ public void iterationShouldWorksAsExpected()
7070
assertFalse( result.next() );
7171
}
7272

73+
@Test
74+
public void firstPastFirstShouldFail()
75+
{
76+
// GIVEN
77+
ResultCursor result = createResult( 3 );
78+
result.next();
79+
result.next();
80+
81+
82+
// THEN
83+
expectedException.expect( NoSuchRecordException.class );
84+
85+
// THEN
86+
result.first();
87+
}
88+
7389
@Test
7490
public void firstOfFieldNameShouldWorkAsExpected()
7591
{
@@ -92,6 +108,50 @@ public void firstOfFieldIndexShouldWorkAsExpected()
92108
assertFalse( result.atEnd() );
93109
}
94110

111+
@Test
112+
public void singlePastFirstShouldFail()
113+
{
114+
// GIVEN
115+
ResultCursor result = createResult( 2 );
116+
result.next();
117+
result.next();
118+
119+
120+
// THEN
121+
expectedException.expect( NoSuchRecordException.class );
122+
123+
// THEN
124+
result.single();
125+
}
126+
127+
@Test
128+
public void singleNoneShouldFail()
129+
{
130+
// GIVEN
131+
ResultCursor result = createResult( 0 );
132+
133+
134+
// THEN
135+
expectedException.expect( NoSuchRecordException.class );
136+
137+
// THEN
138+
result.single();
139+
}
140+
141+
@Test
142+
public void singleWhenMoreThanOneShouldFail()
143+
{
144+
// GIVEN
145+
ResultCursor result = createResult( 2 );
146+
147+
148+
// THEN
149+
expectedException.expect( NoSuchRecordException.class );
150+
151+
// THEN
152+
result.single();
153+
}
154+
95155
@Test
96156
public void singleOfFieldNameShouldWorkAsExpected()
97157
{

0 commit comments

Comments
 (0)