Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion homework-g596-ivanova/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mipt-java-2016</artifactId>
<groupId>ru.mipt.java2016</groupId>
<groupId>
ru.mipt.java2016</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>homework-g596-ivanova</artifactId>

<properties>
<spring.boot.version>1.4.2.RELEASE</spring.boot.version>
</properties>
<dependencies>
<dependency>
<groupId>ru.mipt.java2016</groupId>
Expand All @@ -35,8 +40,66 @@
<version>3.21.0-GA</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jeval</groupId>
<artifactId>jeval</artifactId>
<version>0.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${spring.boot.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>

<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.5.1</version>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>

<build>
<plugins>
<!-- Prepares Agent JAR before test execution -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package ru.mipt.java2016.homework.g596.ivanova.task4;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import ru.mipt.java2016.homework.base.task1.ParsingException;

@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.execute("CREATE TABLE IF NOT EXISTS billing.variables " +
"(username VARCHAR, name VARCHAR, value DOUBLE)");
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS billing.functions " +
"(username VARCHAR, name VARCHAR, arguments VARCHAR, expression VARCHAR)");
addUserIfNotExists("username", "password", true);
}

boolean addUserIfNotExists(String username, String password, boolean enabled) {
try {
loadUser(username);
return false;
} catch (EmptyResultDataAccessException e) {
jdbcTemplate.update("INSERT INTO billing.users VALUES (?, ?, ?)",
new Object[]{username, password, enabled});
return true;
}
}

public Double getVariable(String username, String variable) {
return jdbcTemplate.queryForObject(
"SELECT username, name, value FROM billing.variables WHERE username = ? AND name = ?",
new Object[]{username, variable},
new RowMapper<Double>() {
@Override
public Double mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getDouble("value");
}
}
);
}

Map<String, Double> getVariables(String username) {
try {
return jdbcTemplate.queryForObject(
"SELECT username, name, value FROM billing.variables WHERE username = ?",
new Object[] {username}, (rs, rowNum) -> {
HashMap<String, Double> result = new HashMap<>();
while (true) {
result.put(rs.getString("name"), rs.getDouble("value"));
if (!rs.next()) {
break;
}
}
return result;
});
} catch (EmptyResultDataAccessException e) {
HashMap<String, Double> result = new HashMap<>();
return result;
}
}

boolean deleteVariable(String username, String name) throws ParsingException {
try {
getVariable(username, name);
jdbcTemplate.update("DELETE FROM billing.variables WHERE username = ? AND name = ?",
new Object[]{username, name});
return true;
} catch (EmptyResultDataAccessException e) {
return false;
}
}

void addVariable(String username, String name, Double value) throws ParsingException {
try {
getVariable(username, name);
jdbcTemplate.update("DELETE FROM billing.variables WHERE username = ? AND name = ?",
new Object[]{username, name});
jdbcTemplate.update("INSERT INTO billing.variables VALUES (?, ?, ?)",
new Object[]{username, name, value});
} catch (EmptyResultDataAccessException e) {
jdbcTemplate.update("INSERT INTO billing.variables VALUES (?, ?, ?)",
new Object[]{username, name, value});
}
}

public Function getFunction(String username, String function) {
return jdbcTemplate.queryForObject(
"SELECT username, name, arguments, expression FROM billing.functions WHERE username = ? AND name = ?",
new Object[]{username, function}, (rs, rowNum) -> {
String name = rs.getString("name");
List<String> arguments = Arrays.asList(rs.getString("arguments").split(" "));
String expression = rs.getString("expression");
return new Function(name, arguments, expression);
});
}

void addFunction(String username, String name, List<String> arguments, String expression) throws ParsingException {
try {
getFunction(username, name);
jdbcTemplate.update("DELETE FROM billing.functions WHERE username = ? AND name = ?",
new Object[]{username, name});
String stringArguments = String.join(" ", arguments);
jdbcTemplate.update("INSERT INTO billing.functions VALUES (?, ?, ?, ?)",
new Object[]{username, name, stringArguments, expression});
} catch (EmptyResultDataAccessException e) {
String stringArguments = String.join(" ", arguments);
jdbcTemplate.update("INSERT INTO billing.functions VALUES (?, ?, ?, ?)",
new Object[]{username, name, stringArguments, expression});
}
}

Map<String, Function> getFunctions(String username) {
try {
return jdbcTemplate.queryForObject(
"SELECT username, name, arguments, expression FROM billing.functions WHERE username = ?",
new Object[]{username}, (rs, rowNum) -> {
HashMap<String, Function> result = new HashMap<>();
while (true) {
String name = rs.getString("name");
List<String> arguments = Arrays.asList(rs.getString("arguments").split(" "));
String expression = rs.getString("expression");
result.put(name, new Function(name, arguments, expression));
if (!rs.next()) {
break;
}
}
return result;
});
} catch (EmptyResultDataAccessException e) {
HashMap<String, Function> result = new HashMap<>();
return result;
}
}

boolean deleteFunction(String username, String name) throws ParsingException {
try {
getFunction(username, name);
jdbcTemplate.update("DELETE FROM billing.variables WHERE username = ? AND name = ?",
new Object[]{username, name});
return true;
} catch (EmptyResultDataAccessException e) {
return false;
}
}

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")
);
}
}
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.mipt.java2016.homework.g596.ivanova.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.g596.ivanova.task4.jdbcUrl}") String jdbcUrl,
@Value("${ru.mipt.java2016.homework.g596.ivanova.task4.username:}") String username,
@Value("${ru.mipt.java2016.homework.g596.ivanova.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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package ru.mipt.java2016.homework.g596.ivanova.task4;

public class BillingUser {
private final String username;
private final String password;
private final boolean enabled;

public BillingUser(String username, String password, boolean enabled) {
if (username == null) {
throw new IllegalArgumentException("Null username is not allowed");
}
if (password == null) {
throw new IllegalArgumentException("Null password is not allowed");
}
this.username = username;
this.password = password;
this.enabled = enabled;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public boolean isEnabled() {
return enabled;
}

@Override
public String toString() {
return "BillingUser{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", enabled=" + enabled +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

BillingUser that = (BillingUser) o;

if (enabled != that.enabled) {
return false;
}
if (!username.equals(that.username)) {
return false;
}
return password.equals(that.password);

}

@Override
public int hashCode() {
int result = username.hashCode();
result = 31 * result + password.hashCode();
result = 31 * result + (enabled ? 1 : 0);
return result;
}
}
Loading