diff --git a/AlgebraicDataflowArchitectureModel/.classpath b/AlgebraicDataflowArchitectureModel/.classpath index 3e99697..dfdecbb 100644 --- a/AlgebraicDataflowArchitectureModel/.classpath +++ b/AlgebraicDataflowArchitectureModel/.classpath @@ -1,12 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/AlgebraicDataflowArchitectureModel/lib/postgresql-42.7.4.jar b/AlgebraicDataflowArchitectureModel/lib/postgresql-42.7.4.jar new file mode 100644 index 0000000..091b4d1 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/lib/postgresql-42.7.4.jar Binary files differ diff --git a/AlgebraicDataflowArchitectureModel/models/DatabaseTest.model b/AlgebraicDataflowArchitectureModel/models/DatabaseTest.model new file mode 100644 index 0000000..0ba12a5 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/DatabaseTest.model @@ -0,0 +1,15 @@ +channel LoadDatabase { + out database(dbs: Map, load(url: Str, user: Str, pass: Str)) = insert(dbs, url, {"user": user, "password": pass, "query": "", "result": ""}) +} + +channel executeQuery(url: Str) { + out database.{url}.query(query: Str, execute(newQuery)) = newQuery +} + +native channel sendQuery(url: Str) { + in database.{url}.query(query: Str, sendQuery(newQuery)) = newQuery +} + +native channel setResult(url: Str) { + out database.{url}.result(resutlt: Str, setResult(newResult: Str)) = newResult +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/application/simulator/UISimulatorWindow.java b/AlgebraicDataflowArchitectureModel/src/application/simulator/UISimulatorWindow.java index d3d03a6..0f4448a 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/simulator/UISimulatorWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/simulator/UISimulatorWindow.java @@ -4,6 +4,7 @@ import javax.swing.JPanel; import simulator.Simulator; +import simulator.interfaces.db.DatabasePresenter; import simulator.interfaces.rest.RestPresenter; import simulator.interfaces.swing.SwingPresenter; import simulator.interfaces.timers.TimerService; @@ -17,6 +18,7 @@ private TimerService timerService; private RestPresenter rest; + private DatabasePresenter db; public UISimulatorWindow(Simulator simulator) { setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); @@ -24,6 +26,7 @@ mainPanel = new JPanel(); presenter = new SwingPresenter(mainPanel, simulator); rest = new RestPresenter(simulator); + db = new DatabasePresenter(simulator); this.add(mainPanel); timerService = new TimerService(simulator); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/DatabasePresenter.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/DatabasePresenter.java new file mode 100644 index 0000000..0378c89 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/DatabasePresenter.java @@ -0,0 +1,56 @@ +package simulator.interfaces.db; + +import models.algebra.Expression; +import models.algebra.Term; +import models.dataConstraintModel.ResourcePath; +import models.dataFlowModel.DataTransferChannel; +import simulator.Event; +import simulator.Resource; +import simulator.ResourceIdentifier; +import simulator.Simulator; +import simulator.SystemState; +import simulator.interfaces.INativeReceiver; + +public class DatabasePresenter implements INativeReceiver{ + + + public final String sendQueryChannelName = "sendQuery"; + public final String setResultChannelName = "setResult"; + + protected Simulator simulator; + + protected DataTransferChannel sendQueryChannel; + protected DataTransferChannel setResultChannel; + + public DatabasePresenter(Simulator simulator) { + this.simulator = simulator; + sendQueryChannel = (DataTransferChannel) simulator.getModel().getChannel(sendQueryChannelName); + setResultChannel = (DataTransferChannel) simulator.getModel().getInputChannel(setResultChannelName); + simulator.addNativeReceiver(this, sendQueryChannel); + } + + @Override + public void onReceiveFromModel(Event event, SystemState nextSystemState) { + Expression message = event.getMessage(); + ResourcePath path = event.getInputResourcePath(); + ResourceIdentifier ri = event.getResourceIdentifier(path); + String dbUrl = ri.getPathParams().get(0).toString().replace("\"", ""); + if(message instanceof Term && ((Term) message).getChildren().size() >= 1) { + Expression query = ((Term) message).getChild(0); + System.out.println(simulator.getCurState()); + String user = simulator.getCurState().getResource("database." + dbUrl + ".user").getState().getValue().toString().replace("\"", ""); + String pass = simulator.getCurState().getResource("database." + dbUrl + ".password").getState().getValue().toString().replace("\"", ""); + + System.out.println(user); + System.out.println(pass); + + Resource sqlRes = nextSystemState.getResource(event.getInputResource().getResourceIdentifier()); + Resource resultRes = sqlRes.getParent().getChildrenMap().get("result"); + + ResourcePath resPath = setResultChannel.getOutputResources().iterator().next(); + ResultSender sender = new ResultSender(simulator, setResultChannel, resPath, resultRes, dbUrl, user, pass); + sender.executeQuery(query.toString().replace("\"", "")); + } + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/ResultSender.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/ResultSender.java new file mode 100644 index 0000000..bcf9e07 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/db/ResultSender.java @@ -0,0 +1,70 @@ +package simulator.interfaces.db; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import models.algebra.Constant; +import models.algebra.Expression; +import models.algebra.Term; +import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.ResourcePath; +import models.dataFlowModel.DataTransferChannel; +import simulator.Resource; +import simulator.Simulator; +import simulator.interfaces.NativeSender; + +public class ResultSender extends NativeSender{ + + private String url; + private String user; + private String pass; + + public ResultSender(Simulator simulator, DataTransferChannel channel, ResourcePath resourcePath, + Resource resource, String url, String user, String pass) { + super(simulator, channel, resourcePath, resource); + this.url = url; + this.user = user; + this.pass = pass; + } + + public void executeQuery(String query) { + StringBuilder resCSV = new StringBuilder(); + try( + Connection conn = DriverManager.getConnection(url, user, pass); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(query) + ){ + var meta = rs.getMetaData(); + for(int i = 1; i <= meta.getColumnCount(); i++) { + resCSV.append(meta.getColumnName(i)); + if(i != meta.getColumnCount()) { + resCSV.append(","); + } else { + resCSV.append("\n"); + } + } + while(rs.next()) { + for(int i = 1; i <= meta.getColumnCount(); i++) { + resCSV.append(rs.getString(i)); + if(i != meta.getColumnCount()) { + resCSV.append(","); + } else { + resCSV.append("\n"); + } + } + } + } catch(SQLException e) { + resCSV.append("sql error"); + e.printStackTrace(); + } + Constant res = new Constant(resCSV.toString(), DataConstraintModel.typeString); + Expression message = channel.getOutputChannelMembers().iterator().next().getStateTransition().getMessageExpression(); + message = (Term) message.clone(); + ((Term) message).setChild(0, res); + sendToModel(message); + } + +}