mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 01:43:47 +01:00
Fix up ctrl+C handling in into_sqlite
(#12130)
I noticed that ctrl+C handling wasn't fully wired up in `into sqlite`, for some data types we were ignoring ctrl+C presses. I fixed that up and also made sure we roll back the current transaction when cancelling (without that, I think we leak memory and database locks).
This commit is contained in:
parent
14d1c67863
commit
71ffd04ae7
@ -164,17 +164,23 @@ fn operate(
|
|||||||
let file_name: Spanned<String> = call.req(engine_state, stack, 0)?;
|
let file_name: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||||
let table_name: Option<Spanned<String>> = call.get_flag(engine_state, stack, "table-name")?;
|
let table_name: Option<Spanned<String>> = call.get_flag(engine_state, stack, "table-name")?;
|
||||||
let table = Table::new(&file_name, table_name)?;
|
let table = Table::new(&file_name, table_name)?;
|
||||||
|
let ctrl_c = engine_state.ctrlc.clone();
|
||||||
|
|
||||||
match action(input, table, span) {
|
match action(input, table, span, ctrl_c) {
|
||||||
Ok(val) => Ok(val.into_pipeline_data()),
|
Ok(val) => Ok(val.into_pipeline_data()),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: PipelineData, table: Table, span: Span) -> Result<Value, ShellError> {
|
fn action(
|
||||||
|
input: PipelineData,
|
||||||
|
table: Table,
|
||||||
|
span: Span,
|
||||||
|
ctrl_c: Option<Arc<AtomicBool>>,
|
||||||
|
) -> Result<Value, ShellError> {
|
||||||
match input {
|
match input {
|
||||||
PipelineData::ListStream(list_stream, _) => {
|
PipelineData::ListStream(list_stream, _) => {
|
||||||
insert_in_transaction(list_stream.stream, list_stream.ctrlc, span, table)
|
insert_in_transaction(list_stream.stream, span, table, ctrl_c)
|
||||||
}
|
}
|
||||||
PipelineData::Value(
|
PipelineData::Value(
|
||||||
Value::List {
|
Value::List {
|
||||||
@ -182,9 +188,9 @@ fn action(input: PipelineData, table: Table, span: Span) -> Result<Value, ShellE
|
|||||||
internal_span,
|
internal_span,
|
||||||
},
|
},
|
||||||
_,
|
_,
|
||||||
) => insert_in_transaction(vals.into_iter(), None, internal_span, table),
|
) => insert_in_transaction(vals.into_iter(), internal_span, table, ctrl_c),
|
||||||
PipelineData::Value(val, _) => {
|
PipelineData::Value(val, _) => {
|
||||||
insert_in_transaction(std::iter::once(val), None, span, table)
|
insert_in_transaction(std::iter::once(val), span, table, ctrl_c)
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::OnlySupportsThisInputType {
|
_ => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list".into(),
|
exp_input_type: "list".into(),
|
||||||
@ -197,9 +203,9 @@ fn action(input: PipelineData, table: Table, span: Span) -> Result<Value, ShellE
|
|||||||
|
|
||||||
fn insert_in_transaction(
|
fn insert_in_transaction(
|
||||||
stream: impl Iterator<Item = Value>,
|
stream: impl Iterator<Item = Value>,
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
|
||||||
span: Span,
|
span: Span,
|
||||||
mut table: Table,
|
mut table: Table,
|
||||||
|
ctrl_c: Option<Arc<AtomicBool>>,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
let mut stream = stream.peekable();
|
let mut stream = stream.peekable();
|
||||||
let first_val = match stream.peek() {
|
let first_val = match stream.peek() {
|
||||||
@ -210,10 +216,16 @@ fn insert_in_transaction(
|
|||||||
let table_name = table.name().clone();
|
let table_name = table.name().clone();
|
||||||
let tx = table.try_init(first_val)?;
|
let tx = table.try_init(first_val)?;
|
||||||
|
|
||||||
// insert all the records
|
for stream_value in stream {
|
||||||
stream.try_for_each(|stream_value| {
|
if let Some(ref ctrlc) = ctrl_c {
|
||||||
if let Some(ref ctrlc) = ctrlc {
|
|
||||||
if ctrlc.load(Ordering::Relaxed) {
|
if ctrlc.load(Ordering::Relaxed) {
|
||||||
|
tx.rollback().map_err(|e| ShellError::GenericError {
|
||||||
|
error: "Failed to rollback SQLite transaction".into(),
|
||||||
|
msg: e.to_string(),
|
||||||
|
span: None,
|
||||||
|
help: None,
|
||||||
|
inner: Vec::new(),
|
||||||
|
})?;
|
||||||
return Err(ShellError::InterruptedByUser { span: None });
|
return Err(ShellError::InterruptedByUser { span: None });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,8 +261,8 @@ fn insert_in_transaction(
|
|||||||
inner: Vec::new(),
|
inner: Vec::new(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
result
|
result?
|
||||||
})?;
|
}
|
||||||
|
|
||||||
tx.commit().map_err(|e| ShellError::GenericError {
|
tx.commit().map_err(|e| ShellError::GenericError {
|
||||||
error: "Failed to commit SQLite transaction".into(),
|
error: "Failed to commit SQLite transaction".into(),
|
||||||
|
Loading…
Reference in New Issue
Block a user