Skip to content

Commit b281ef1

Browse files
committed
Added variants of single and first for simplified access
Rationale: @jakewins and @boggle observed that sometimes using single and first leads to rather long expressions and felt adding this sugar might help with that
1 parent c1b604a commit b281ef1

File tree

3 files changed

+124
-28
lines changed

3 files changed

+124
-28
lines changed

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,13 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21-
import java.util.ArrayList;
22-
import java.util.List;
23-
24-
import org.neo4j.driver.v1.Function;
25-
import org.neo4j.driver.v1.Record;
26-
import org.neo4j.driver.v1.RecordAccessor;
27-
import org.neo4j.driver.v1.ResultCursor;
28-
import org.neo4j.driver.v1.ResultSummary;
29-
import org.neo4j.driver.v1.Value;
21+
import org.neo4j.driver.v1.*;
3022
import org.neo4j.driver.v1.exceptions.ClientException;
3123
import org.neo4j.driver.v1.exceptions.NoSuchRecordException;
3224

25+
import java.util.ArrayList;
26+
import java.util.List;
27+
3328
import static java.lang.String.format;
3429
import static java.util.Collections.emptyList;
3530
import static org.neo4j.driver.v1.Records.recordAsIs;
@@ -197,6 +192,19 @@ public Record first()
197192
return record();
198193
}
199194

195+
196+
@Override
197+
public Value first(String fieldName) throws NoSuchRecordException
198+
{
199+
return first().get( fieldName );
200+
}
201+
202+
@Override
203+
public Value first(int index) throws NoSuchRecordException
204+
{
205+
return first().get( index );
206+
}
207+
200208
@Override
201209
public Record single()
202210
{
@@ -210,6 +218,18 @@ public Record single()
210218
return first;
211219
}
212220

221+
@Override
222+
public Value single( String fieldName ) throws NoSuchRecordException
223+
{
224+
return single().get( fieldName );
225+
}
226+
227+
@Override
228+
public Value single( int index ) throws NoSuchRecordException
229+
{
230+
return single().get( index );
231+
}
232+
213233
@Override
214234
public Record peek()
215235
{

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

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
*/
1919
package org.neo4j.driver.v1;
2020

21-
import java.util.List;
22-
2321
import org.neo4j.driver.v1.exceptions.ClientException;
2422
import org.neo4j.driver.v1.exceptions.NoSuchRecordException;
2523

24+
import java.util.List;
25+
2626

2727
/**
2828
* The result of running a statement, a stream of records represented as a cursor.
@@ -100,6 +100,28 @@ public interface ResultCursor extends RecordAccessor, Resource
100100
*/
101101
Record first() throws NoSuchRecordException;
102102

103+
/**
104+
* 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.
106+
*
107+
* @param fieldName the name of the field to return from the first record in the stream
108+
* @return the specified field from the first record in the stream
109+
* @throws NoSuchRecordException if there is no first record or the cursor has been used already
110+
*
111+
*/
112+
Value first( String fieldName ) throws NoSuchRecordException;
113+
114+
/**
115+
* 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.
117+
*
118+
* @param index the index of the field to return from the first record in the stream
119+
* @return the specified field from the first record in the stream
120+
* @throws NoSuchRecordException if there is no first record or the cursor has been used already
121+
*
122+
*/
123+
Value first( int index ) throws NoSuchRecordException;
124+
103125
/**
104126
* Move to the first record and return an immutable copy of it, failing if there is not exactly
105127
* one record in the stream, or if this cursor has already been used to move "into" the stream.
@@ -109,6 +131,26 @@ public interface ResultCursor extends RecordAccessor, Resource
109131
*/
110132
Record single() throws NoSuchRecordException;
111133

134+
/**
135+
* 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.
137+
*
138+
* @param fieldName the name of the field to return from the first and only record in the stream
139+
* @return the value of the specified field of the first and only record in the stream
140+
* @throws NoSuchRecordException if there is not exactly one record in the stream, or if the cursor has been used already
141+
*/
142+
Value single( String fieldName ) throws NoSuchRecordException;
143+
144+
/**
145+
* 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.
147+
*
148+
* @param index the index of the field to return from the first and only record in the stream
149+
* @return the value of the specified field of the first and only record in the stream
150+
* @throws NoSuchRecordException if there is not exactly one record in the stream, or if the cursor has been used already
151+
*/
152+
Value single( int index ) throws NoSuchRecordException;
153+
112154
/**
113155
* Investigate the next upcoming record without changing the position of this cursor.
114156
*
@@ -157,4 +199,4 @@ public interface ResultCursor extends RecordAccessor, Resource
157199
* @return a summary for the whole query
158200
*/
159201
ResultSummary summarize();
160-
}
202+
}

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

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,19 @@
2222
import org.junit.Rule;
2323
import org.junit.Test;
2424
import org.junit.rules.ExpectedException;
25-
26-
import java.util.ArrayList;
27-
import java.util.Arrays;
28-
import java.util.List;
29-
3025
import org.neo4j.driver.internal.summary.ResultBuilder;
3126
import org.neo4j.driver.internal.value.NullValue;
32-
import org.neo4j.driver.v1.Pair;
33-
import org.neo4j.driver.v1.Record;
34-
import org.neo4j.driver.v1.RecordAccessor;
35-
import org.neo4j.driver.v1.Records;
36-
import org.neo4j.driver.v1.ResultCursor;
37-
import org.neo4j.driver.v1.Value;
27+
import org.neo4j.driver.v1.*;
3828
import org.neo4j.driver.v1.exceptions.ClientException;
3929
import org.neo4j.driver.v1.exceptions.NoSuchRecordException;
4030

31+
import java.util.ArrayList;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
4135
import static org.hamcrest.CoreMatchers.equalTo;
4236
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
43-
import static org.junit.Assert.assertFalse;
44-
import static org.junit.Assert.assertNotNull;
45-
import static org.junit.Assert.assertNull;
46-
import static org.junit.Assert.assertThat;
47-
import static org.junit.Assert.assertTrue;
37+
import static org.junit.Assert.*;
4838
import static org.neo4j.driver.v1.Values.value;
4939

5040
public class InternalResultCursorTest
@@ -80,6 +70,50 @@ public void iterationShouldWorksAsExpected()
8070
assertFalse( result.next() );
8171
}
8272

73+
@Test
74+
public void firstOfFieldNameShouldWorkAsExpected()
75+
{
76+
// GIVEN
77+
ResultCursor result = createResult( 3 );
78+
79+
// THEN
80+
assertThat( result.first( "k1" ), equalTo( value("v1-1") ) );
81+
assertFalse( result.atEnd() );
82+
}
83+
84+
@Test
85+
public void firstOfFieldIndexShouldWorkAsExpected()
86+
{
87+
// GIVEN
88+
ResultCursor result = createResult( 3 );
89+
90+
// THEN
91+
assertThat( result.first( 0 ), equalTo( value("v1-1") ) );
92+
assertFalse( result.atEnd() );
93+
}
94+
95+
@Test
96+
public void singleOfFieldNameShouldWorkAsExpected()
97+
{
98+
// GIVEN
99+
ResultCursor result = createResult( 1 );
100+
101+
// THEN
102+
assertThat( result.single( "k1" ), equalTo( value("v1-1") ) );
103+
assertTrue( result.atEnd() );
104+
}
105+
106+
@Test
107+
public void singleOfFieldIndexShouldWorkAsExpected()
108+
{
109+
// GIVEN
110+
ResultCursor result = createResult( 1 );
111+
112+
// THEN
113+
assertThat( result.single( 0 ), equalTo( value("v1-1") ) );
114+
assertTrue( result.atEnd() );
115+
}
116+
83117
@Test
84118
public void firstThrowsOnEmptyStream()
85119
{

0 commit comments

Comments
 (0)