Первый

This commit is contained in:
2025-01-31 07:32:03 +05:00
parent 7b012ae698
commit 07d3be1938
24 changed files with 1196 additions and 0 deletions

View File

@ -0,0 +1,488 @@
package org.ccalm.sync;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.ServletContextAware;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import org.springframework.web.multipart.MultipartFile;
import tctable.TCField;
import tctable.TCTable;
import tctable.TCTableTools;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
@Controller
public class MainController implements ServletContextAware {
private static final Logger logger = LoggerFactory.getLogger(MainController.class);
@Value("${spring.application.name}")
String application_name = "";
@Value("${spring.datasource.url}")
String db_url="";
@Value("${spring.datasource.username}")
String db_login="";
@Value("${spring.datasource.password}")
String db_password="";
private ServletContext context;
@Override
public void setServletContext(ServletContext servletContext) {
this.context = servletContext;
}
@RequestMapping(value = "/",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8")
@ResponseBody
public String index(Model model, @RequestParam(required=false,name="lng",defaultValue = "1") String language_id) {
JSONObject json = new JSONObject();
try {
json.put("error_code",0);
json.put("error_message","");
json.put("error_marker",(String)null);
String buildDate="";
//String buildVersion="";
try {
InputStream inputStream = MainController.class.getClassLoader().getResourceAsStream("META-INF/build-info.properties");
if (inputStream != null) {
Properties properties = new Properties();
properties.load(inputStream);
buildDate = properties.getProperty("build.time");
//buildVersion = properties.getProperty("build.version");
}
} catch (Exception e) {
e.printStackTrace();
}
json.put("build_date",buildDate);
//json.put("build_version",buildVersion);
json.put("name",application_name);
//json.put("active_connections",dataSource.getHikariPoolMXBean().getActiveConnections());
//json.put("idle_connections",dataSource.getHikariPoolMXBean().getIdleConnections());
} catch (JSONException e) {
throw new RuntimeException(e);
}
return json.toString();
}
//Скачать с удалённого сервера
@RequestMapping(value = "/download/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Object download(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
System.out.println("/asdc/tctable/");
JSONObject result = new JSONObject();
result.put("error_code", 0);
result.put("error_message", "");
byte[] reqData=null;
if(file!=null) {
try {
reqData = file.getBytes();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if(reqData==null)
return "OK";
Connection conn = null;
try {
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection(db_url, db_login, db_password);
try {
Statement sttTZ = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
sttTZ.executeUpdate("SET TIME ZONE 'UTC';");
sttTZ.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
InputStream isRaw = null;
isRaw = new ByteArrayInputStream(reqData);
TCTable tbl = new TCTable("", 0);
try {
if (tbl.OpenTableH(isRaw)) {
if(tbl.name.equals("frmlocustdel_locations")) {
while (tbl.ReadNextRecord()) {
String uid=tbl.fields.get(0).getStrVal();
if(uid==null || uid.isEmpty()) continue; //Для не пропуска переходных записей...
boolean exists = false; //Is there a record.
Statement st;
try {
ResultSet rs = null;
st = conn.createStatement();
try {
String sql = "select 1 from main.frmlocustdel_locations where uid=main.strtouuid('"+uid+"')";
rs = st.executeQuery(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
if (rs != null) {
if (rs.next())
exists = true;
}
st.close();
PreparedStatement stmt = null;
String sql = "";
if (exists) {
sql = """
update main.frmlocustdel_locations set
del=?,
seq=?,
frmlocustdel_uid=main.strtouuid(?),
pos=?,
lon=?,
lat=?
where
uid=main.strtouuid(?)
""";
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} else {
sql = """
insert into main.frmlocustdel_locations(
del,
seq,
frmlocustdel_uid,
pos,
lon,
lat,
uid
)values(
?,
?,
main.strtouuid(?),
?,
?,
?,
main.strtouuid(?)
)
""";
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
}
try {
stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
stmt.setString(3, tbl.fields.get(3).getStrVal());
stmt.setInt(4, tbl.fields.get(4).getIntVal());
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
stmt.setString(7, tbl.fields.get(0).getStrVal());
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
//Выпоняю запрос на свтавку либо обновление
try {
stmt.execute();
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
}
}else{
//Если это универсальная функция по обновлению данных (похожая функция есть в андроид приложении)
//Проверка на существование полей в обеих таблицах
ExistsType[] fb=new ExistsType[tbl.fields.size()];
Map<String, String> col = TCTableTools.getTableSchema(conn, "main", tbl.name);
for(int i=0;i<tbl.fields.size();i++)
{
Iterator<Map.Entry<String, String>> iterator = col.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getKey().equalsIgnoreCase(col.get(i))) {
fb[i].exists=true;
fb[i].type=entry.getValue();
break;
}
}
}
//Переписываем значения существующих полей и выполняем запросы
while(tbl.ReadNextRecord())
{
String sql=null;
String[] par=null;
if(tbl.getRowByName("id")!=null && tbl.getRowByName("id").getStrVal()!=null){
sql="select 1 from main."+tbl.name+" where id = ?";
par = new String[] { tbl.getRowByName("id").getStrVal() };
}else if(tbl.getRowByName("uid")!=null && tbl.getRowByName("id").getStrVal()!=null){
sql="select 1 from main."+tbl.name+" where uid = main.strtouuid(?)";
par = new String[] { tbl.getRowByName("uid").getStrVal() };
}
if(sql==null)
continue;
boolean exists=false;
ResultSet rs = null;
Statement st = conn.createStatement();
try {
rs = st.executeQuery(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
if (rs != null) {
if (rs.next())
exists = true;
}
st.close();
PreparedStatement stmt = null;
sql = "";
if (exists) {
sql="update main."+tbl.name+" set ";
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid"))
sql+=tbl.fields.get(i).name+"=?,";
}
}
sql=sql.substring(0, sql.length() - 1);
sql+="where uid=main.strtouuid(?)";
} else {
sql="insert into main."+tbl.name+"(";
String subSql1=" ";
String subSql2=" ";
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid")) {
subSql1 += tbl.fields.get(i).name + ",";
subSql2 += "?,";
}
}
}
subSql1 += "uid,";
subSql2 += "?,";
subSql1=subSql1.substring(0, subSql1.length() - 1);
subSql2=subSql1.substring(0, subSql2.length() - 1);
sql+=subSql1+")values("+subSql2+");";
}
try {
stmt = conn.prepareStatement(sql);
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
try {
for(int i=0;i<tbl.fields.size();i++)
{
if(fb[i].exists){
if(!tbl.fields.get(i).name.equals("uid")) {
if(tbl.fields.get(i).isNull()){
stmt.setNull(i, Types.NULL);
}else{
switch (tbl.fields.get(i).type){
case TCField.BD_UINT1, TCField.BD_UINT2, TCField.BD_UINT4:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_UINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_SUINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_INT1, TCField.BD_INT2, TCField.BD_INT4:
stmt.setInt(i, tbl.fields.get(i).getIntVal());
break;
case TCField.BD_INT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_SINT8:
stmt.setLong(i, tbl.fields.get(i).getLongVal());
break;
case TCField.BD_FLOAT4:
stmt.setFloat(i, tbl.fields.get(i).getFloatVal());
break;
case TCField.BD_FLOAT8:
stmt.setDouble(i, tbl.fields.get(i).getDoubleVal());
break;
case TCField.BD_SFLOAT8:
stmt.setBigDecimal(i, tbl.fields.get(i).getBigDecimalVal());
break;
case TCField.BD_UTF8_1,TCField.BD_UTF8_2,TCField.BD_UTF8_4:
stmt.setString(i, tbl.fields.get(i).getStrVal());
break;
}
}
}
}
}
/*stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
stmt.setString(3, tbl.fields.get(3).getStrVal());
stmt.setInt(4, tbl.fields.get(4).getIntVal());
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
stmt.setString(7, tbl.fields.get(0).getStrVal());*/
} catch (SQLException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}
} catch (Exception ex) {
ex.printStackTrace();
logger.error("Error:",ex);
result.put("error_code",1);
result.put("error_message", ex.getMessage());
return result.toString();
}finally {
if(conn!=null) { try { conn.close(); } catch (SQLException e) { } }
}
return result.toString();
}
//отдать с текущего сервера
@RequestMapping(value = "/upload/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public Object upload(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
String result;
String sql="select * from main.commands where seq>0";
//Connect to database
Connection conn = null;
try {
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection(db_url, db_login, db_password);
if (conn != null) {
logger.info("Connect is OK!");
} else {
logger.info("An error occurred while connecting to the database!");
}
try {
Statement st = conn.createStatement();
ResultSet rs=null;
try {
rs = st.executeQuery(sql);
} catch( SQLException ex ) {
logger.error("Error",ex);
}
if(rs!=null)
{
TCTable tbl=new TCTable(pN,123456);
logger.info("*** "+pN+" ***");
ResultSetMetaData rsmd = rs.getMetaData();
for(int i=1;i<=rsmd.getColumnCount();i++)
{
logger.info(i+") name="+rsmd.getColumnName(i)+" type="+rsmd.getColumnTypeName(i));
TCField field=new TCField(rsmd.getColumnName(i), rsmd.getColumnTypeName(i));
tbl.addField(field);
}
tbl.getHeader(response.getOutputStream());
while (rs.next())
{
for(int i=1;i<=rsmd.getColumnCount();i++)
{
if(!rsmd.getColumnTypeName(i).equals("geometry")) {
tbl.fields.get(i - 1).setValue(rs.getString(i));
//logger.info(String.valueOf(i)+") "+rs.getString(i));
}else {
tbl.fields.get(i - 1).setValue(null);
}
}
//Save binary data to stream
tbl.getCol(response.getOutputStream());
}
}
st.close();
//response.getOutputStream();
response.flushBuffer();
} catch (IOException e) {
logger.error("Error",e);
}
} catch (Exception ex) {
logger.error("Error",ex);
}finally {
if(conn!=null) {try { conn.close(); } catch (SQLException e) {} }
}
return result;
}
}

View File

@ -0,0 +1,13 @@
package org.ccalm.sync;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SyncApplication {
public static void main(String[] args) {
SpringApplication.run(SyncApplication.class, args);
}
}

Binary file not shown.

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Please check if the user has access to the directory from which the application is being executed -->
<property name="LOGS" value="logs" />
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/${appName}.log</file>
<encoder>
<pattern>{"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}","thread":"[%thread]","level":"%level","logger":"%logger{36}","marker":"%X{marker}","message":"%msg"}%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS}/${appName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} | %level | %logger{36} | %X{marker} | %msg%n</pattern>
</encoder>
</appender>
<!--root level="info"-->
<root level="warn">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@ -0,0 +1,13 @@
package org.ccalm.sync;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SyncApplicationTests {
@Test
void contextLoads() {
}
}