1717import java .nio .file .Path ;
1818import java .util .Map ;
1919
20+ import org .eclipse .rdf4j .common .transaction .IsolationLevel ;
21+ import org .eclipse .rdf4j .common .transaction .IsolationLevels ;
2022import org .eclipse .rdf4j .console .ConsoleIO ;
2123import org .eclipse .rdf4j .console .ConsoleState ;
2224import org .eclipse .rdf4j .console .LockRemover ;
@@ -49,10 +51,11 @@ public String getHelpShort() {
4951
5052 @ Override
5153 public String getHelpLong () {
52- return PrintHelp .USAGE + "load <file-or-url> [from <base-uri>] [into <context-id>]\n "
54+ return PrintHelp .USAGE + "load <file-or-url> [from <base-uri>] [into <context-id>] [isolation <level>] \n "
5355 + " <file-or-url> The path or URL identifying the data file\n "
5456 + " <base-uri> The base URI to use for resolving relative references, defaults to <file-or-url>\n "
5557 + " <context-id> The ID of the context to add the data to, e.g. foo:bar or _:n123\n "
58+ + " <level> Isolation level to use when loading data (defaults to NONE)\n "
5659 + "Loads the specified data file into the current repository\n " ;
5760 }
5861
@@ -83,21 +86,43 @@ public void execute(final String... tokens) {
8386 } else {
8487 String baseURI = null ;
8588 String context = null ;
89+ IsolationLevel isolationLevel = null ;
8690
8791 int index = 2 ;
88- if (tokens .length >= index + 2 && tokens [index ].equalsIgnoreCase ("from" )) {
89- baseURI = tokens [index + 1 ];
90- index += 2 ;
91- }
92- if (tokens .length >= index + 2 && tokens [index ].equalsIgnoreCase ("into" )) {
93- context = tokens [tokens .length - 1 ];
94- index += 2 ;
95- }
96- if (index < tokens .length ) {
97- writeln (getHelpLong ());
98- } else {
99- load (repository , baseURI , context , tokens );
92+ while (index < tokens .length ) {
93+ if (tokens [index ].equalsIgnoreCase ("from" )) {
94+ if (tokens .length < index + 2 ) {
95+ writeln (getHelpLong ());
96+ return ;
97+ }
98+ baseURI = tokens [index + 1 ];
99+ index += 2 ;
100+ } else if (tokens [index ].equalsIgnoreCase ("into" )) {
101+ if (tokens .length < index + 2 ) {
102+ writeln (getHelpLong ());
103+ return ;
104+ }
105+ context = tokens [index + 1 ];
106+ index += 2 ;
107+ } else if (tokens [index ].equalsIgnoreCase ("isolation" )) {
108+ if (tokens .length < index + 2 ) {
109+ writeln (getHelpLong ());
110+ return ;
111+ }
112+ try {
113+ isolationLevel = IsolationLevels .valueOf (tokens [index + 1 ].toUpperCase ());
114+ } catch (IllegalArgumentException e ) {
115+ writeError ("Unknown isolation level: " + tokens [index + 1 ]);
116+ return ;
117+ }
118+ index += 2 ;
119+ } else {
120+ writeln (getHelpLong ());
121+ return ;
122+ }
100123 }
124+
125+ load (repository , baseURI , context , isolationLevel , tokens );
101126 }
102127 }
103128 }
@@ -114,12 +139,14 @@ private Path getWorkDir() {
114139 /**
115140 * Load data into a repository
116141 *
117- * @param repository repository
142+ * @param repository repository
118143 * @param baseURI
119144 * @param context
145+ * @param isolationLevel explicit isolation level, or null to prompt for default
120146 * @param tokens
121147 */
122- private void load (Repository repository , String baseURI , String context , final String ... tokens ) {
148+ private void load (Repository repository , String baseURI , String context , IsolationLevel isolationLevel ,
149+ final String ... tokens ) {
123150 final String dataPath = tokens [1 ];
124151 URL dataURL = null ;
125152 File dataFile = null ;
@@ -136,7 +163,17 @@ private void load(Repository repository, String baseURI, String context, final S
136163 }
137164
138165 try {
139- addData (repository , baseURI , context , dataURL , dataFile );
166+ IsolationLevel levelToUse = isolationLevel ;
167+ if (levelToUse == null ) {
168+ boolean confirmed = consoleIO
169+ .askProceed ("No isolation level specified. Use isolation level NONE?" , false );
170+ if (!confirmed ) {
171+ return ;
172+ }
173+ levelToUse = IsolationLevels .NONE ;
174+ }
175+
176+ addData (repository , baseURI , context , dataURL , dataFile , levelToUse );
140177 } catch (RepositoryReadOnlyException e ) {
141178 handleReadOnlyException (repository , e , tokens );
142179 } catch (MalformedURLException e ) {
@@ -179,26 +216,37 @@ private void handleReadOnlyException(Repository repository, RepositoryReadOnlyEx
179216 /**
180217 * Add data from a URL or local file. If the dataURL is null, then the datafile will be used.
181218 *
182- * @param repository repository
183- * @param baseURI base URI
184- * @param context context (can be null)
185- * @param dataURL url of the data
186- * @param dataFile file containing data
219+ * @param repository repository
220+ * @param baseURI base URI
221+ * @param context context (can be null)
222+ * @param dataURL url of the data
223+ * @param dataFile file containing data
224+ * @param isolationLevel isolation level to use for the transaction
187225 * @throws RepositoryException
188226 * @throws IOException
189227 * @throws RDFParseException
190228 */
191- private void addData (Repository repository , String baseURI , String context , URL dataURL , File dataFile )
192- throws RepositoryException , IOException , RDFParseException {
229+ private void addData (Repository repository , String baseURI , String context , URL dataURL , File dataFile ,
230+ IsolationLevel isolationLevel ) throws RepositoryException , IOException , RDFParseException {
193231 Resource [] contexts = getContexts (repository , context );
194232 writeln ("Loading data..." );
195233
196234 final long startTime = System .nanoTime ();
197235 try (RepositoryConnection con = repository .getConnection ()) {
198- if (dataURL == null ) {
199- con .add (dataFile , baseURI , null , contexts );
200- } else {
201- con .add (dataURL , baseURI , null , contexts );
236+ con .begin (isolationLevel );
237+ try {
238+ if (dataURL == null ) {
239+ con .add (dataFile , baseURI , null , contexts );
240+ } else {
241+ con .add (dataURL , baseURI , null , contexts );
242+ }
243+ con .commit ();
244+ } catch (RepositoryException | RDFParseException | IOException e ) {
245+ con .rollback ();
246+ throw e ;
247+ } catch (RuntimeException e ) {
248+ con .rollback ();
249+ throw e ;
202250 }
203251 }
204252 final long endTime = System .nanoTime ();
0 commit comments