-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
4th task Dmitriyeva g597 #343
base: master
Are you sure you want to change the base?
Changes from all commits
98d5a09
24e0019
cec8865
7e45c0e
78bbc56
3b2d4cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,255 @@ | ||
package ru.mipt.java2016.homework.g597.dmitrieva.task4; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.dao.EmptyResultDataAccessException; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
import org.springframework.stereotype.Repository; | ||
import ru.mipt.java2016.homework.base.task1.ParsingException; | ||
|
||
import javax.annotation.PostConstruct; | ||
import javax.sql.DataSource; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.util.*; | ||
|
||
@Repository | ||
public class BillingDao { | ||
private static final Logger LOG = LoggerFactory.getLogger(BillingDao.class); | ||
|
||
@Autowired | ||
private DataSource dataSource; | ||
|
||
private JdbcTemplate jdbcTemplate; | ||
|
||
@PostConstruct | ||
public void postConstruct() { | ||
jdbcTemplate = new JdbcTemplate(dataSource, false); | ||
initSchema(); | ||
} | ||
|
||
public void initSchema() { | ||
LOG.trace("Initializing schema"); | ||
jdbcTemplate.execute("CREATE SCHEMA IF NOT EXISTS billing"); | ||
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS billing.users " + | ||
"(username VARCHAR PRIMARY KEY, password VARCHAR, enabled BOOLEAN)"); | ||
//jdbcTemplate.update("INSERT INTO billing.users VALUES ('username', 'password', TRUE)"); | ||
|
||
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS billing.functions" + | ||
"(username VARCHAR, nameOfFunction VARCHAR, arguments VARCHAR, " + | ||
"expression VARCHAR, PRIMARY KEY (username, nameOfFunction))"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а что делает |
||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','sin', 'a', 'sin(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','cos', 'a', 'cos(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','tg', 'a', 'tg(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','sqrt', 'a', 'sqrt(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','pow', 'm, e', 'pow(m, e)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','abs', 'a', 'abs(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','sign', 'a', 'sigh(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','log', 'a, n', 'log(a, n)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username', 'log2', 'a', 'log2(a)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username', 'rnd', '', 'rnd()')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','max', 'a, b', 'max(a, b)')"); | ||
//jdbcTemplate.update("INSERT INTO billing.functions VALUES ('username','min', 'a, b', 'min(a,b)')"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. каеф |
||
|
||
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS billing.variables " + | ||
"(username VARCHAR, nameOfVariable VARCHAR, valueOfVariable DOUBLE NOT NULL, " + | ||
" PRIMARY KEY (username, nameOfVariable))"); | ||
|
||
} | ||
|
||
public BillingUser loadUser(String username) throws EmptyResultDataAccessException { | ||
LOG.trace("Querying for user " + username); | ||
return jdbcTemplate.queryForObject( | ||
"SELECT username, password, enabled FROM billing.users WHERE username = ?", | ||
new Object[]{username}, | ||
new RowMapper<BillingUser>() { | ||
@Override | ||
public BillingUser mapRow(ResultSet rs, int rowNum) throws SQLException { | ||
return new BillingUser( | ||
rs.getString("username"), | ||
rs.getString("password"), | ||
rs.getBoolean("enabled") | ||
); | ||
} | ||
} | ||
); | ||
} | ||
|
||
public void addUser(String username, String password) { | ||
LOG.trace("Adding user " + username); | ||
jdbcTemplate.update("INSERT INTO billing.users VALUES ('" + username + "', '" + password + "', TRUE)"); | ||
} | ||
|
||
public Double getVariable(String username, String variableName) { | ||
return jdbcTemplate.queryForObject("SELECT username, nameOfVariable, valueOfVariable " + | ||
"FROM billing.variables WHERE username = ? AND nameOfVariable = ?", | ||
new Object[]{username, variableName}, | ||
new RowMapper<Double>() { | ||
@Override | ||
public Double mapRow(ResultSet resultSet, int rowNum) throws SQLException { | ||
return resultSet.getDouble("valueOfVariable"); | ||
} | ||
} | ||
); | ||
} | ||
|
||
Map<String, Double> getVariables(String username) { | ||
try { | ||
return jdbcTemplate.queryForObject( | ||
"SELECT username, nameOfVariable, valueOfVariable FROM billing.variables WHERE username = ?", | ||
new Object[]{username}, | ||
new RowMapper<TreeMap<String, Double>>() { | ||
@Override | ||
public TreeMap<String, Double> mapRow(ResultSet resultSet, int rowNum) throws SQLException { | ||
TreeMap<String, Double> selection = new TreeMap<String, Double>(); | ||
while (true) { | ||
selection.put(resultSet.getString("nameOfVariable"), | ||
resultSet.getDouble("valueOfVariable")); | ||
if (!resultSet.next()) { | ||
break; | ||
} | ||
} | ||
return selection; | ||
} | ||
} | ||
); | ||
} catch (EmptyResultDataAccessException e) { | ||
return new TreeMap<>(); | ||
} | ||
} | ||
|
||
boolean deleteVariable(String username, String nameOfVariable) { | ||
try { | ||
getVariable(username, nameOfVariable); | ||
jdbcTemplate.update("DELETE FROM billing.variables WHERE username = ? AND nameOfVariable = ?", | ||
new Object[]{username, nameOfVariable}); | ||
return true; | ||
} catch (EmptyResultDataAccessException e) { | ||
return false; | ||
} | ||
} | ||
|
||
public void addVariable(String username, String nameOfVariable, Double valueOfVariable) throws ParsingException { | ||
try { | ||
getVariable(username, nameOfVariable); | ||
jdbcTemplate.update("DELETE FROM billing.variables WHERE username = ? AND nameOfVariable = ?", | ||
new Object[]{username, nameOfVariable}); | ||
jdbcTemplate.update("INSERT INTO billing.variables VALUES (?, ?, ?)", | ||
new Object[]{username, nameOfVariable, valueOfVariable}); | ||
} catch (EmptyResultDataAccessException e) { | ||
jdbcTemplate.update("INSERT INTO billing.variables VALUES (?, ?, ?)", | ||
new Object[]{username, nameOfVariable, valueOfVariable}); | ||
} | ||
} | ||
|
||
public Function getFunction(String username, String nameOfFunction) { | ||
return jdbcTemplate.queryForObject( | ||
"SELECT username, nameOfFunction, arguments, expression " + | ||
"FROM billing.functions WHERE username = ? AND nameOfFunction = ?", | ||
new Object[]{username, nameOfFunction}, | ||
new RowMapper<Function>() { | ||
@Override | ||
public Function mapRow(ResultSet resultSet, int rowNum) throws SQLException { | ||
String nameOfFunction = resultSet.getString("nameOfFunction"); | ||
List<String> arguments = Arrays.asList(resultSet.getString("arguments").split(" ")); | ||
String expression = resultSet.getString("expression"); | ||
return new Function(nameOfFunction, arguments, expression); | ||
} | ||
} | ||
); | ||
} | ||
|
||
|
||
TreeMap<String, Function> getFunctions(String username) { | ||
try { | ||
return jdbcTemplate.queryForObject("SELECT username, nameOfFunction, arguments, expression" + | ||
" FROM billing.functions WHERE username = ?", | ||
new Object[]{username}, | ||
new RowMapper<TreeMap<String, Function>>() { | ||
@Override | ||
public TreeMap<String, Function> mapRow(ResultSet resultSet, int rowNum) throws SQLException { | ||
TreeMap<String, Function> selection = new TreeMap(); | ||
while (true) { | ||
String nameOfFunction = resultSet.getString("nameOfFunction"); | ||
List<String> arguments = Arrays.asList(resultSet.getString("arguments").split(" ")); | ||
String expression = resultSet.getString("expression"); | ||
selection.put(nameOfFunction, new Function(nameOfFunction, arguments, expression)); | ||
if (!resultSet.next()) { | ||
break; | ||
} | ||
} | ||
return selection; | ||
} | ||
}); | ||
} catch (EmptyResultDataAccessException e) { | ||
return new TreeMap<>(); | ||
} | ||
} | ||
|
||
boolean deleteFunction(String username, String nameOfFunction) { | ||
try { | ||
getFunction(username, nameOfFunction); | ||
jdbcTemplate.update("DELETE FROM billing.functions WHERE username = ? AND nameOfFunction = ?", | ||
new Object[]{username, nameOfFunction}); | ||
return true; | ||
} catch (EmptyResultDataAccessException e) { | ||
return false; | ||
} | ||
} | ||
|
||
void addFunction(String username, String nameOfFunction, List<String> arguments, String expression) { | ||
// Заменяем в функции все вхождения переменных на их значения | ||
int beginIndexOfVariable = 0; | ||
int endIndexOfVariable = 0; | ||
boolean isReadingVariable = false; | ||
for (int i = 0; i < expression.length(); i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ммм, парсинг в классе для работы с базой данных. KPACUBO. |
||
// Нашли что-то, что начинается с буквы -- возможно, это переменная | ||
if (Character.isLetter(expression.charAt(i)) && !isReadingVariable) { | ||
beginIndexOfVariable = i; | ||
endIndexOfVariable = i; // ??? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. без комментария непонятно было, что происходит, а теперь всё встало на свои места |
||
isReadingVariable = true; | ||
continue; | ||
} | ||
// находимся в процессе чтения переменной (если это она) | ||
if ((Character.isLetterOrDigit(expression.charAt(i)) || expression.charAt(i) == '_') && isReadingVariable) { | ||
endIndexOfVariable = i; | ||
continue; | ||
} | ||
if (!(Character.isLetterOrDigit(expression.charAt(i)) || expression.charAt(i) == '_') | ||
&& isReadingVariable) { | ||
isReadingVariable = false; | ||
String variable = expression.substring(beginIndexOfVariable, endIndexOfVariable + 1); | ||
// Если мы нашли не переменную, а какую-то функцию, то ничего с ней делать не хотим | ||
if (getFunctions(username).containsKey(variable)) { | ||
continue; | ||
} | ||
// Если какую-то переменную мы нашли, но в списке переменных это пользователя ее нет, | ||
// значит, это просто аргумент функции и можно расслабиться | ||
if (!getVariables(username).containsKey(variable)) { | ||
continue; | ||
} | ||
// Если же это действительно переменная, добавленная пользователем, | ||
// то получаем ее значение | ||
String value = getVariable(username, variable).toString(); | ||
// Заменяем ее первое вхождение на значение | ||
expression.replaceFirst(variable, value); | ||
// Дальше обновляем счетчик и снова ищем какую-нибудь переменную | ||
i = 0; | ||
} | ||
} | ||
try { | ||
getFunction(username, nameOfFunction); | ||
jdbcTemplate.update("DELETE FROM billing.functions WHERE username = ? AND nameOfFunction = ?", | ||
new Object[]{username, nameOfFunction}); | ||
String stringOfArguments = String.join(" ", arguments); | ||
jdbcTemplate.update("INSERT INTO billing.functions VALUES (?, ?, ?, ?)", | ||
new Object[]{username, nameOfFunction, stringOfArguments, expression}); | ||
} catch (EmptyResultDataAccessException e) { | ||
String stringArguments = String.join(" ", arguments); | ||
jdbcTemplate.update("INSERT INTO billing.functions VALUES (?, ?, ?, ?)", | ||
new Object[]{username, nameOfFunction, stringArguments, expression}); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package ru.mipt.java2016.homework.g597.dmitrieva.task4; | ||
|
||
import com.zaxxer.hikari.HikariConfig; | ||
import com.zaxxer.hikari.HikariDataSource; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import javax.sql.DataSource; | ||
|
||
@Configuration | ||
public class BillingDatabaseConfiguration { | ||
@Bean | ||
public DataSource billingDataSource( | ||
@Value("${ru.mipt.java2016.homework.g597.dmitriyeva.task4.jdbcUrl:jdbc:h2:~/test}") String jdbcUrl, | ||
@Value("${ru.mipt.java2016.homework.g597.dmitriyeva.task4.username:}") String username, | ||
@Value("${ru.mipt.java2016.homework.g597.dmitriyeva.task4.password:}") String password | ||
) { | ||
HikariConfig config = new HikariConfig(); | ||
config.setDriverClassName(org.h2.Driver.class.getName()); | ||
config.setJdbcUrl(jdbcUrl); | ||
config.setUsername(username); | ||
config.setPassword(password); | ||
return new HikariDataSource(config); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
это типа для первого запуска, а потом закомментить? это оскорбляет чувства семинаристов, которые не знают о таких подводных камнях изначально
на будущее, для этого есть
MERGE
.