Lines 60-65
Link Here
|
60 |
import java.util.concurrent.Future; |
60 |
import java.util.concurrent.Future; |
61 |
import java.util.logging.Level; |
61 |
import java.util.logging.Level; |
62 |
import java.util.logging.Logger; |
62 |
import java.util.logging.Logger; |
|
|
63 |
import javax.swing.SwingUtilities; |
63 |
import org.netbeans.modules.db.dataview.meta.DBColumn; |
64 |
import org.netbeans.modules.db.dataview.meta.DBColumn; |
64 |
import org.netbeans.modules.db.dataview.meta.DBConnectionFactory; |
65 |
import org.netbeans.modules.db.dataview.meta.DBConnectionFactory; |
65 |
import org.netbeans.modules.db.dataview.meta.DBException; |
66 |
import org.netbeans.modules.db.dataview.meta.DBException; |
Lines 70-75
Link Here
|
70 |
import org.openide.DialogDisplayer; |
71 |
import org.openide.DialogDisplayer; |
71 |
import org.openide.NotifyDescriptor; |
72 |
import org.openide.NotifyDescriptor; |
72 |
import org.openide.util.Cancellable; |
73 |
import org.openide.util.Cancellable; |
|
|
74 |
import org.openide.util.Mutex; |
73 |
import org.openide.util.NbBundle; |
75 |
import org.openide.util.NbBundle; |
74 |
import org.openide.util.RequestProcessor; |
76 |
import org.openide.util.RequestProcessor; |
75 |
|
77 |
|
Lines 92-98
Link Here
|
92 |
} |
94 |
} |
93 |
|
95 |
|
94 |
void initialDataLoad() throws SQLException { |
96 |
void initialDataLoad() throws SQLException { |
95 |
|
97 |
assert (! SwingUtilities.isEventDispatchThread()) : "Must be called of the EDT!"; |
|
|
98 |
|
96 |
/** |
99 |
/** |
97 |
* Wrap initializing the SQL result into a runnable. This makes it |
100 |
* Wrap initializing the SQL result into a runnable. This makes it |
98 |
* possible to wait for the result in the main thread and cancel the |
101 |
* possible to wait for the result in the main thread and cancel the |
Lines 295-300
Link Here
|
295 |
final DBTable table, |
298 |
final DBTable table, |
296 |
final String insertSQL, |
299 |
final String insertSQL, |
297 |
final Object[] insertedRow) { |
300 |
final Object[] insertedRow) { |
|
|
301 |
dataView.setEditable(false); |
302 |
|
298 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_insert"); |
303 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_insert"); |
299 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
304 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
300 |
|
305 |
|
Lines 337-353
Link Here
|
337 |
|
342 |
|
338 |
@Override |
343 |
@Override |
339 |
protected void executeOnSucess() { |
344 |
protected void executeOnSucess() { |
340 |
if (pageContext.getTotalRows() < 0) { |
345 |
// refresh when required |
341 |
pageContext.setTotalRows(0); |
346 |
Boolean needRequery = Mutex.EVENT.readAccess(new Mutex.Action<Boolean>() { |
342 |
pageContext.first(); |
347 |
@Override |
343 |
} |
348 |
public Boolean run() { |
344 |
pageContext.incrementRowSize(1); |
349 |
if (pageContext.getTotalRows() < 0) { |
|
|
350 |
pageContext.setTotalRows(0); |
351 |
pageContext.first(); |
352 |
} |
353 |
pageContext.incrementRowSize(1); |
345 |
|
354 |
|
346 |
// refresh when required |
355 |
return pageContext.refreshRequiredOnInsert(); |
347 |
if (pageContext.refreshRequiredOnInsert()) { |
356 |
}; |
|
|
357 |
}); |
358 |
if(needRequery) { |
348 |
SQLExecutionHelper.this.executeQuery(); |
359 |
SQLExecutionHelper.this.executeQuery(); |
349 |
} else { |
360 |
} else { |
350 |
reinstateToolbar(); |
361 |
Mutex.EVENT.readAccess(new Runnable() { |
|
|
362 |
@Override |
363 |
public void run() { |
364 |
reinstateToolbar(); |
365 |
} |
366 |
}); |
351 |
} |
367 |
} |
352 |
} |
368 |
} |
353 |
}; |
369 |
}; |
Lines 358-393
Link Here
|
358 |
} |
374 |
} |
359 |
|
375 |
|
360 |
void executeDeleteRow(final DataViewPageContext pageContext, final DBTable table, final DataViewTableUI rsTable) { |
376 |
void executeDeleteRow(final DataViewPageContext pageContext, final DBTable table, final DataViewTableUI rsTable) { |
|
|
377 |
dataView.setEditable(false); |
378 |
|
379 |
SQLStatementGenerator generator = dataView.getSQLStatementGenerator(); |
361 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_delete"); |
380 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_delete"); |
362 |
final int[] rows = rsTable.getSelectedRows(); |
381 |
|
363 |
for(int i = 0; i < rows.length; i++) { |
382 |
class DeleteElement { |
364 |
rows[i] = rsTable.convertRowIndexToModel(rows[i]); |
383 |
public List<Object> values = new ArrayList<Object>(); |
|
|
384 |
public List<Integer> types = new ArrayList<Integer>(); |
385 |
public String sql; |
365 |
} |
386 |
} |
366 |
Arrays.sort(rows); |
387 |
|
|
|
388 |
final List<DeleteElement> rows = new ArrayList<DeleteElement>(); |
389 |
for(int viewRow: rsTable.getSelectedRows()) { |
390 |
int modelRow = rsTable.convertRowIndexToModel(viewRow); |
391 |
DeleteElement de = new DeleteElement(); |
392 |
de.sql = generator.generateDeleteStatement(table, de.types, de.values, modelRow, rsTable.getModel()); |
393 |
rows.add(de); |
394 |
} |
395 |
|
367 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
396 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
368 |
|
|
|
369 |
@Override |
397 |
@Override |
370 |
public void execute() throws SQLException, DBException { |
398 |
public void execute() throws SQLException, DBException { |
371 |
dataView.setEditable(false); |
399 |
dataView.setEditable(false); |
372 |
for (int j = (rows.length - 1); j >= 0 && !error; j--) { |
400 |
for (DeleteElement de: rows) { |
373 |
if (Thread.currentThread().isInterrupted()) { |
401 |
if (Thread.currentThread().isInterrupted() || error) { |
374 |
break; |
402 |
break; |
375 |
} |
403 |
} |
376 |
deleteARow(rows[j], rsTable.getModel()); |
404 |
deleteARow(de); |
377 |
} |
405 |
} |
378 |
} |
406 |
} |
379 |
|
407 |
|
380 |
private void deleteARow(int rowNum, DataViewTableUIModel tblModel) throws SQLException, DBException { |
408 |
private void deleteARow(DeleteElement deleteRow) throws SQLException, DBException { |
381 |
final List<Object> values = new ArrayList<Object>(); |
409 |
PreparedStatement pstmt = conn.prepareStatement(deleteRow.sql); |
382 |
final List<Integer> types = new ArrayList<Integer>(); |
|
|
383 |
|
384 |
SQLStatementGenerator generator = dataView.getSQLStatementGenerator(); |
385 |
final String deleteStmt = generator.generateDeleteStatement(table, types, values, rowNum, tblModel); |
386 |
PreparedStatement pstmt = conn.prepareStatement(deleteStmt); |
387 |
try { |
410 |
try { |
388 |
int pos = 1; |
411 |
int pos = 1; |
389 |
for (Object val : values) { |
412 |
for (Object val : deleteRow.values) { |
390 |
DBReadWriteHelper.setAttributeValue(pstmt, pos, types.get(pos - 1), val); |
413 |
DBReadWriteHelper.setAttributeValue(pstmt, pos, deleteRow.types.get(pos - 1), val); |
391 |
pos++; |
414 |
pos++; |
392 |
} |
415 |
} |
393 |
|
416 |
|
Lines 413-419
Link Here
|
413 |
|
436 |
|
414 |
@Override |
437 |
@Override |
415 |
protected void executeOnSucess() { |
438 |
protected void executeOnSucess() { |
416 |
pageContext.decrementRowSize(rows.length); |
439 |
pageContext.decrementRowSize(rows.size()); |
417 |
SQLExecutionHelper.this.executeQuery(); |
440 |
SQLExecutionHelper.this.executeQuery(); |
418 |
} |
441 |
} |
419 |
}; |
442 |
}; |
Lines 424-431
Link Here
|
424 |
} |
447 |
} |
425 |
|
448 |
|
426 |
void executeUpdateRow(final DBTable table, final DataViewTableUI rsTable, final boolean selectedOnly) { |
449 |
void executeUpdateRow(final DBTable table, final DataViewTableUI rsTable, final boolean selectedOnly) { |
|
|
450 |
dataView.setEditable(false); |
451 |
|
452 |
SQLStatementGenerator generator = dataView.getSQLStatementGenerator(); |
427 |
final DataViewTableUIModel dataViewTableUIModel = rsTable.getModel(); |
453 |
final DataViewTableUIModel dataViewTableUIModel = rsTable.getModel(); |
428 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_update"); |
454 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_update"); |
|
|
455 |
|
456 |
class UpdateElement { |
457 |
public List<Object> values = new ArrayList<Object>(); |
458 |
public List<Integer> types = new ArrayList<Integer>(); |
459 |
public String sql; |
460 |
public Integer key; |
461 |
} |
462 |
|
463 |
final List<UpdateElement> updateSet = new ArrayList<UpdateElement>(); |
464 |
|
465 |
int[] viewRows = rsTable.getSelectedRows(); |
466 |
List<Integer> modelRows = new ArrayList<Integer>(); |
467 |
for(Integer viewRow: viewRows) { |
468 |
modelRows.add(rsTable.convertRowIndexToModel(viewRow)); |
469 |
} |
470 |
|
471 |
for (Integer key : dataViewTableUIModel.getUpdateKeys()) { |
472 |
if (modelRows.contains(key) || (!selectedOnly)) { |
473 |
UpdateElement ue = new UpdateElement(); |
474 |
try { |
475 |
ue.key = key; |
476 |
ue.sql = generator.generateUpdateStatement(table, key, |
477 |
dataViewTableUIModel.getChangedData(key), ue.values, ue.types, |
478 |
rsTable.getModel()); |
479 |
updateSet.add(ue); |
480 |
} catch (DBException ex) { |
481 |
// The model protects against illegal values, so rethrow |
482 |
throw new RuntimeException(ex); |
483 |
} |
484 |
} |
485 |
} |
486 |
|
487 |
|
429 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
488 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") { |
430 |
|
489 |
|
431 |
private PreparedStatement pstmt; |
490 |
private PreparedStatement pstmt; |
Lines 433-479
Link Here
|
433 |
|
492 |
|
434 |
@Override |
493 |
@Override |
435 |
public void execute() throws SQLException, DBException { |
494 |
public void execute() throws SQLException, DBException { |
436 |
dataView.setEditable(false); |
495 |
for (UpdateElement ue : updateSet) { |
437 |
if (selectedOnly) { |
496 |
if(Thread.interrupted()) { |
438 |
updateSelected(); |
497 |
break; |
439 |
} else { |
|
|
440 |
for (Integer key : dataViewTableUIModel.getUpdateKeys()) { |
441 |
if (Thread.currentThread().isInterrupted()) { |
442 |
break; |
443 |
} else { |
444 |
updateARow(key); |
445 |
keysToRemove.add(key); |
446 |
} |
447 |
} |
498 |
} |
|
|
499 |
updateARow(ue); |
500 |
keysToRemove.add(ue.key); |
448 |
} |
501 |
} |
449 |
} |
502 |
} |
450 |
|
503 |
|
451 |
private void updateSelected() throws SQLException, DBException { |
504 |
private void updateARow(UpdateElement ue) throws SQLException, DBException { |
452 |
int[] rows = rsTable.getSelectedRows(); |
505 |
pstmt = conn.prepareStatement(ue.sql); |
453 |
for (int j = 0; j < rows.length && !error; j++) { |
|
|
454 |
Set<Integer> keys = dataViewTableUIModel.getUpdateKeys(); |
455 |
for (Integer key : keys) { |
456 |
if (Thread.currentThread().isInterrupted()) { |
457 |
break; |
458 |
} else if (key == rows[j]) { |
459 |
updateARow(key); |
460 |
keysToRemove.add(key); |
461 |
} |
462 |
} |
463 |
} |
464 |
} |
465 |
|
466 |
private void updateARow(Integer key) throws SQLException, DBException { |
467 |
SQLStatementGenerator generator = dataView.getSQLStatementGenerator(); |
468 |
|
469 |
List<Object> values = new ArrayList<Object>(); |
470 |
List<Integer> types = new ArrayList<Integer>(); |
471 |
String updateStmt = generator.generateUpdateStatement(table, key, dataViewTableUIModel.getChangedData(key), values, types, rsTable.getModel()); |
472 |
|
473 |
pstmt = conn.prepareStatement(updateStmt); |
474 |
int pos = 1; |
506 |
int pos = 1; |
475 |
for (Object val : values) { |
507 |
for (Object val : ue.values) { |
476 |
DBReadWriteHelper.setAttributeValue(pstmt, pos, types.get(pos - 1), val); |
508 |
DBReadWriteHelper.setAttributeValue(pstmt, pos, ue.types.get(pos - 1), val); |
477 |
pos++; |
509 |
pos++; |
478 |
} |
510 |
} |
479 |
|
511 |
|
Lines 500-510
Link Here
|
500 |
|
532 |
|
501 |
@Override |
533 |
@Override |
502 |
protected void executeOnSucess() { |
534 |
protected void executeOnSucess() { |
503 |
DataViewTableUIModel tblContext = rsTable.getModel(); |
535 |
Mutex.EVENT.writeAccess(new Runnable() { |
504 |
for (Integer key : keysToRemove) { |
536 |
@Override |
505 |
tblContext.removeUpdateForSelectedRow(key, false); |
537 |
public void run() { |
506 |
} |
538 |
DataViewTableUIModel tblContext = rsTable.getModel(); |
507 |
reinstateToolbar(); |
539 |
for (Integer key : keysToRemove) { |
|
|
540 |
tblContext.removeUpdateForSelectedRow(key, false); |
541 |
} |
542 |
|
543 |
reinstateToolbar(); |
544 |
} |
545 |
}); |
508 |
} |
546 |
} |
509 |
}; |
547 |
}; |
510 |
RequestProcessor.Task task = rp.create(executor); |
548 |
RequestProcessor.Task task = rp.create(executor); |
Lines 555-562
Link Here
|
555 |
task.schedule(0); |
593 |
task.schedule(0); |
556 |
} |
594 |
} |
557 |
|
595 |
|
|
|
596 |
void executeQueryOffEDT() { |
597 |
rp.post(new Runnable() { |
598 |
@Override |
599 |
public void run() { |
600 |
executeQuery(); |
601 |
} |
602 |
}); |
603 |
} |
604 |
|
558 |
// Once Data View is created the it assumes the query never changes. |
605 |
// Once Data View is created the it assumes the query never changes. |
559 |
void executeQuery() { |
606 |
void executeQuery() { |
|
|
607 |
assert (! SwingUtilities.isEventDispatchThread()); |
608 |
|
560 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_executequery"); |
609 |
String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_executequery"); |
561 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, dataView.getSQLString()) { |
610 |
SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, dataView.getSQLString()) { |
562 |
|
611 |
|
Lines 662-668
Link Here
|
662 |
task.schedule(0); |
711 |
task.schedule(0); |
663 |
} |
712 |
} |
664 |
|
713 |
|
665 |
void loadDataFrom(DataViewPageContext pageContext, ResultSet rs, boolean getTotal) throws SQLException { |
714 |
private void loadDataFrom(final DataViewPageContext pageContext, ResultSet rs, boolean getTotal) throws SQLException { |
666 |
if (rs == null) { |
715 |
if (rs == null) { |
667 |
return; |
716 |
return; |
668 |
} |
717 |
} |
Lines 670-676
Link Here
|
670 |
int pageSize = pageContext.getPageSize(); |
719 |
int pageSize = pageContext.getPageSize(); |
671 |
int startFrom = pageContext.getCurrentPos(); |
720 |
int startFrom = pageContext.getCurrentPos(); |
672 |
|
721 |
|
673 |
List<Object[]> rows = new ArrayList<Object[]>(); |
722 |
final List<Object[]> rows = new ArrayList<Object[]>(); |
674 |
int colCnt = pageContext.getTableMetaData().getColumnCount(); |
723 |
int colCnt = pageContext.getTableMetaData().getColumnCount(); |
675 |
try { |
724 |
try { |
676 |
boolean hasNext = false; |
725 |
boolean hasNext = false; |
Lines 742-748
Link Here
|
742 |
LOGGER.log(Level.SEVERE, "Failed to set up table model.", e); // NOI18N |
791 |
LOGGER.log(Level.SEVERE, "Failed to set up table model.", e); // NOI18N |
743 |
throw e; |
792 |
throw e; |
744 |
} finally { |
793 |
} finally { |
745 |
pageContext.getModel().setData(rows); |
794 |
Mutex.EVENT.writeAccess(new Mutex.Action<Void>() { |
|
|
795 |
@Override |
796 |
public Void run() { |
797 |
pageContext.getModel().setData(rows); |
798 |
return null; |
799 |
} |
800 |
}); |
746 |
} |
801 |
} |
747 |
} |
802 |
} |
748 |
|
803 |
|