All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wicp.tams.common.binlog.alone.DuckulaAssit Maven / Gradle / Ivy

The newest version!
/*
 * **********************************************************************
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称:common
 * 项目描述:公共的工具集
 * 版权说明:本软件属andy.zhou([email protected])所有。
 * ***********************************************************************
 */
package net.wicp.tams.common.binlog.alone;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.protobuf.InvalidProtocolBufferException;

import net.wicp.tams.common.Conf;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.apiext.jdbc.JdbcAssit;
import net.wicp.tams.common.apiext.json.JSONUtil;
import net.wicp.tams.common.binlog.alone.ListenerConf.ColumnType;
import net.wicp.tams.common.binlog.alone.ListenerConf.DuckulaEvent;
import net.wicp.tams.common.binlog.alone.ListenerConf.DuckulaEvent.Builder;
import net.wicp.tams.common.binlog.alone.ListenerConf.DuckulaEventItem;
import net.wicp.tams.common.binlog.alone.ListenerConf.OptType;
import net.wicp.tams.common.binlog.alone.ListenerConf.Position;
import net.wicp.tams.common.constant.DateFormatCase;
import net.wicp.tams.common.constant.FieldFormart;
import net.wicp.tams.common.constant.dic.YesOrNo;
import net.wicp.tams.common.constant.ods.AddColName;
import net.wicp.tams.common.constant.ods.AddColNameType;

public abstract class DuckulaAssit {
	public static SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public static DuckulaEvent parse(byte[] data) throws InvalidProtocolBufferException {
		DuckulaEvent retobj = DuckulaEvent.parseFrom(data);
		return retobj;
	}

	/***
	 * 逻辑删除变为物理删除。 指定的列有修改表示删除,适合于源表为逻辑删除情况,多条拆分为
	 * 
	 * @param oriData       原始数据
	 * @param changeColName 指定逻辑删除字段名
	 * @param delValue      指定逻辑删除表示为删除的值
	 * @param logic         yes:物理删除变为逻辑删除,no:逻辑删除变为物理删除,null:不做改变
	 * @return
	 */
	public static List parseForUpsetKafka(DuckulaEvent oriData, String changeColName, String delValue,
			YesOrNo logic) {
		List ret = new ArrayList();
		if (oriData == null) {
			return ret;
		}
		int itemsCount = oriData.getItemsCount();
		Builder builder = null;
		if (itemsCount > 1) {
			builder = oriData.toBuilder().clone();
			builder.clearItems();
		}
		for (int i = 0; i < itemsCount; i++) {
			boolean needLogic = false;
			boolean needPhysics = false;
			if (StringUtil.isNull(changeColName) || StringUtil.isNull(delValue) || logic == null) {// 不合法的参数,不支持对冲
				needLogic = false;
				needPhysics = false;
			} else {
				if (logic == YesOrNo.yes && oriData.getOptType() == OptType.delete) {// 需要逻辑删除
					needLogic = true;
				} else {
					needLogic = false;
				}
				if (logic == YesOrNo.no && oriData.getOptType() != OptType.delete) {// 需要物理删除
					String valueAfter = getValueStr(oriData, i, changeColName);
					if (StringUtil.isNull(valueAfter)) {// 指定的changed列没有值,不支持对冲
						needPhysics = false;
					} else if (!delValue.equals(valueAfter)) {// 值不对,不需要做对冲
						needPhysics = false;
					} else {
						needPhysics = true;
					}
				} else {
					needPhysics = false;
				}
			}
			DuckulaEvent retObj = null;
			if (builder != null) {
				Builder clone = builder.clone();
				clone.addItems(oriData.getItems(i));
				if (needPhysics) {
					clone.setOptType(OptType.delete);
				} else if (needLogic) {
					clone.setOptType(OptType.update);
					clone.getItemsBuilder(0).putAfter(changeColName, delValue);
				}
				retObj = clone.build();
			} else {
				if (needPhysics) {
					Builder builder2 = oriData.toBuilder();
					builder2.setOptType(OptType.delete);
					retObj = builder2.build();
				} else if (needLogic) {
					Builder builder2 = oriData.toBuilder();
					builder2.setOptType(OptType.update);
					Map beforeData = builder2.getItemsBuilder(0).getBeforeMap();
					builder2.getItemsBuilder(0).putAllAfter(beforeData);
					builder2.getItemsBuilder(0).putAfter(changeColName, delValue);// 不能直接在beforeData添加,会报错。只能采用这种方式
					retObj = builder2.build();
				} else {
					retObj = oriData;
				}
			}
			ret.add(retObj);
		}
		return ret;
	}

	/***
	 * 得到对冲逻辑,item只有一条记录。
	 * 
	 * @param data
	 * @param changeColName
	 * @param isLogic
	 * @return L:主键json R:数据
	 * @throws InvalidProtocolBufferException
	 */
	public static Pair parseHedge(byte[] data, String changeColName, boolean isLogic)
			throws InvalidProtocolBufferException {
		if (data == null || StringUtil.isNull(changeColName)) {// 不合法的参数,不支持对冲
			return null;
		}
		DuckulaEvent oriData = DuckulaEvent.parseFrom(data);
		if (oriData.getOptType() == OptType.delete) {// 删除逻辑不需要对冲
			return null;
		}
		String valueAfter = getValueAfter(oriData, 0, changeColName);
		if (StringUtil.isNull(valueAfter)) {// 指定的changed列没有值,不支持对冲
			return null;
		}
		Builder oriDataBuilder = oriData.toBuilder();
		
		ObjectMapper objmap=new ObjectMapper();
		
		ObjectNode before = (ObjectNode)JSONUtil.parserStr(objmap, String.valueOf(valueAfter));
		if (before == null || before.isEmpty()) {// 指定的changed列没有值,不支持对冲
			return null;
		}
		ObjectNode keyUpdateJson = JsonNodeFactory.instance.objectNode();
		ObjectNode keyTarget = DuckulaAssit.getKeyJson(oriDataBuilder, 0);
		
		for (Iterator iterator = before.fieldNames(); iterator.hasNext();) {
			String key = iterator.next();
			int keyIndex = oriDataBuilder.getColsList().indexOf(key);
			if (oriDataBuilder.getKeyindexsList().contains(keyIndex)) {// 包括主键
				Serializable keyValue = getValue(oriDataBuilder.getColsType(keyIndex), before.get(key).asText());
				keyUpdateJson.putPOJO(key, keyValue);
				keyTarget.putPOJO(key, keyValue);
			}
			oriDataBuilder.getItemsBuilder(0).putAfter(key, before.get(key).asText());
		}
		
		
		
		if (keyUpdateJson.isEmpty()) {// 没有改变主键
			return null;
		}
		// 如果有lastOpttype字段也需要修改。这样后续就可以做为源数据处理了。
		int optIndex = oriData.getColsList().indexOf(AddColName.lastOpttype.getColNameTrue());
		int isdeleteIndex = oriData.getColsList().indexOf(AddColName.isDelete.getColNameTrue());
		if (isdeleteIndex >= 0) {// 逻辑删除需要设置为1
			oriDataBuilder.getItemsBuilder(0).putAfter(AddColName.isDelete.getColNameTrue(), "1");
		}
		if (isLogic) {
			oriDataBuilder.setOptType(OptType.update);
			if (optIndex >= 0) {
				oriDataBuilder.getItemsBuilder(0).putAfter(AddColName.lastOpttype.getColNameTrue(),
						OptType.update.name());
			}
		} else {
			oriDataBuilder.setOptType(OptType.delete);
			if (optIndex >= 0) {
				oriDataBuilder.getItemsBuilder(0).putAfter(AddColName.lastOpttype.getColNameTrue(),
						OptType.delete.name());
			}
		}
		return Pair.of(keyTarget, oriDataBuilder.build());
	}

	public static boolean isEmpty(CharSequence cs) {
		return cs == null || cs.length() == 0;
	}

	public static Map getColNamesMap(DuckulaEvent duckulaEvent, FieldFormart fieldFormart) {
		Map retmap = new HashMap();
		for (int i = 0; i < duckulaEvent.getColsCount(); i++) {
			retmap.put(duckulaEvent.getCols(i), fieldFormart.getColName(duckulaEvent.getCols(i)));
		}
		return retmap;
	}

	/***
	 * 转换字段名
	 * 
	 * @param oriEvent
	 * @param fieldFormart
	 * @return
	 */
	public static DuckulaEvent convertEvent(DuckulaEvent oriEvent, FieldFormart fieldFormart) {
		if (fieldFormart == FieldFormart.ori) {
			return oriEvent;
		}
		Builder returBuilder = oriEvent.toBuilder();
		if (fieldFormart != FieldFormart.ori) {
			// 列处理
			for (int i = 0; i < returBuilder.getColsCount(); i++) {
				returBuilder.setCols(i, fieldFormart.getColName(returBuilder.getCols(i)));
			}
			// 数据处理
			for (int i = 0; i < returBuilder.getItemsCount(); i++) {
				DuckulaEventItem.Builder newBuilder = DuckulaEventItem.newBuilder();
				DuckulaEventItem.Builder oldBuilder = returBuilder.getItemsBuilder(i);
				newBuilder.setVersion(oldBuilder.getVersion());
				Map afterMap = oldBuilder.getAfterMap();
				if (MapUtils.isNotEmpty(afterMap)) {
					for (String key : afterMap.keySet()) {
						newBuilder.putAfter(fieldFormart.getColName(key), afterMap.get(key));
					}
				}
				Map beforeMap = oldBuilder.getBeforeMap();
				if (MapUtils.isNotEmpty(beforeMap)) {
					for (String key : beforeMap.keySet()) {
						newBuilder.putBefore(fieldFormart.getColName(key), beforeMap.get(key));
					}
				}
				returBuilder.setItems(i, newBuilder);
			}
		}
		return returBuilder.build();
	}

	// 返回数组有点困难
	@SuppressWarnings("unchecked")
	public static  List> getKey(DuckulaEvent.Builder duckulaEventBuilder,
			int index) {
		Map datamap = !isAfter(duckulaEventBuilder.getOptType())
				? duckulaEventBuilder.getItems(index).getBeforeMap()
				: duckulaEventBuilder.getItems(index).getAfterMap();

		Integer[] keysindex = duckulaEventBuilder.getKeyindexsCount() == 0 ? new Integer[] { 0 }
				: duckulaEventBuilder.getKeyindexsList().toArray(new Integer[duckulaEventBuilder.getKeyindexsCount()]);
		List> retlist = new ArrayList>();
		for (int i = 0; i < keysindex.length; i++) {
			String keyName = duckulaEventBuilder.getCols(keysindex[i]);
			String value = datamap.get(keyName);
			ColumnType columnType = duckulaEventBuilder.getColsType(keysindex[i]);
			Serializable retobj = value;
			switch (columnType) {
			case LONGLONG:
				retobj = Long.valueOf(value);
				break;
			case BIT:
			case TINY:
			case SHORT:
			case INT24:
			case LONG:
			case ENUM:
			case SET:
				retobj = Integer.valueOf(value);
				break;
			default:
				break;
			}
			retlist.add(Pair.of(keyName, (T) retobj));
		}
		return retlist;
	}

	/***
	 * 得到主键名
	 * 
	 * @param duckulaEvent
	 * @return
	 */
	public static String[] getKeyColname(DuckulaEvent duckulaEvent) {
		Integer[] keysindex = duckulaEvent.getKeyindexsCount() == 0 ? new Integer[] { 0 }
				: duckulaEvent.getKeyindexsList().toArray(new Integer[duckulaEvent.getKeyindexsCount()]);
		String[] retAry = new String[keysindex.length];
		for (int i = 0; i < retAry.length; i++) {
			retAry[i] = duckulaEvent.getCols(i);
		}
		return retAry;
	}

	public static String getKeyJoin(DuckulaEvent.Builder duckulaEventBuilder, int index, String splitChat) {
		List> keyValues = getKey(duckulaEventBuilder, index);
		String splitChatStr = StringUtils.isEmpty(splitChat) ? "," : splitChat;
		StringBuffer buf = new StringBuffer();
		for (Pair keyValue : keyValues) {
			buf.append(splitChatStr);
			buf.append(keyValue.getRight());
		}
		return buf.substring(1);
	}

	public static ObjectNode getKeyJson(DuckulaEvent.Builder duckulaEventBuilder, int index) {
		List> keyValues = getKey(duckulaEventBuilder, index);
		return PluginAssit.getKeySplit(keyValues);
	}

	/***
	 * 创建只有一个item的DuckulaEvent
	 * 
	 * @param duckulaEventBuilder
	 * @param index
	 * @return
	 */
	public static DuckulaEvent.Builder buildSinglItemDuckulaEvent(DuckulaEvent.Builder duckulaEventBuilder, int index) {
		net.wicp.tams.common.binlog.alone.ListenerConf.DuckulaEvent.Builder duckulaEventbuilder = null;
		while (true) {
			try {
				duckulaEventbuilder = duckulaEventBuilder.clone();
				break;
			} catch (Throwable e) {
				// 20230322 Exception in thread "pool-5-thread-1"
				// java.lang.UnsupportedOperationException
				System.out.println("有时发生clone异常?不明什么原因!已做处理,不会导致数据丢失。" + e.getMessage());
			}
		}
		DuckulaEventItem curItems = duckulaEventbuilder.getItems(index);
		duckulaEventbuilder.clearItems();
		duckulaEventbuilder.addItems(curItems);
		return duckulaEventbuilder;
	}

	/***
	 * 得到变化后数据的值
	 * 
	 * @param duckulaEvent
	 * @param colName
	 * @return
	 */
	public static  T getValueAfter(DuckulaEvent duckulaEvent, int index, String colName) {
		return getValue(duckulaEvent, index, colName, true);
	}

	public static  T getValueBefore(DuckulaEvent duckulaEvent, int index, String colName) {
		return getValue(duckulaEvent, index, colName, false);
	}

	public static  T getValue(DuckulaEvent duckulaEvent, int index, String colName) {
		return getValue(duckulaEvent, index, colName, isAfter(duckulaEvent.getOptType()));
	}

	@SuppressWarnings("unchecked")
	public static  T getValue(DuckulaEvent duckulaEvent, int index, String colName,
			boolean isAfter) {
		if (duckulaEvent.getColsCount() != duckulaEvent.getColsList().size()) {
			throw new RuntimeException("列名与值不一致,请联系相关人员。");
		}
		String value = getValueStr(duckulaEvent, index, colName, isAfter);
		if (isEmpty(value)) {
			return null;
		}
		int colindex = duckulaEvent.getColsList().indexOf(colName);
		Serializable retobj = getValue(duckulaEvent.getColsType(colindex), value);
		return (T) retobj;
	}

	public static Serializable getValue(ColumnType columnType, String value) {
		Serializable retobj = null;
		switch (columnType) {
		case LONGLONG:
			retobj = Long.valueOf(value);
			break;
		case BIT:
		case TINY:
		case SHORT:
		case INT24:
		case LONG:
		case ENUM:
		case SET:
			retobj = Integer.valueOf(value);
			break;
		case FLOAT:
			retobj = Float.valueOf(value);
			break;

		case DOUBLE:
			retobj = Double.valueOf(value);
			break;
		case DECIMAL:
		case NEWDECIMAL:
			retobj = new BigDecimal(value);
			break;
		case GEOMETRY:
			try {
				retobj = Base64.decodeBase64(value);
			} catch (Exception e) {
				retobj = value;
			}
			break;
		case YEAR:
			try {
				retobj = Integer.valueOf(value);
			} catch (Exception e) {
				retobj = value;
			}
			break;
		case TIMESTAMP2:
		case DATETIME2:
			try {
				retobj = formater.parse(value);
			} catch (ParseException e) {
				retobj = value;
			}
			break;
		case BLOB:
		default:
			retobj = value;
			break;
		}
		return retobj;
	}

	public static String getValueStr(DuckulaEvent duckulaEvent, int index, String colName) {
		return getValueStr(duckulaEvent, index, colName, isAfter(duckulaEvent.getOptType()));
	}

	public static String getValueStr(DuckulaEvent duckulaEvent, int index, String colName, boolean isAfter) {
		DuckulaEventItem item = duckulaEvent.getItems(index);
		String value;
		if (isAfter) {
			value = item.getAfterMap().get(colName);
		} else {
			value = item.getBeforeMap().get(colName);
		}
		return value;
	}

	/**
	 * 选取的操作类型
	 * 
	 * @param optType
	 * @return
	 */
	public static boolean isAfter(OptType optType) {
		if (optType == OptType.delete || optType == OptType.updateBefore) {
			return false;
		} else {
			return true;
		}
	}

	public static Map getValueMap(DuckulaEvent duckulaEvent, int index) {
		DuckulaEventItem item = duckulaEvent.getItems(index);
		Map retMap;
		if (isAfter(duckulaEvent.getOptType())) {
			retMap = item.getAfterMap();
		} else {
			retMap = item.getBeforeMap();
		}
		return retMap;
	}

	public static byte[] getBytes(String filePath) {
		byte[] buffer = null;
		try {
			File file = new File(filePath);
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
			byte[] b = new byte[1000];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer;
	}

	public static ObjectNode convertJson(DuckulaEvent duckulaEvent) {
		ObjectNode retobj = JsonNodeFactory.instance.objectNode();
		retobj.putPOJO("optType", duckulaEvent.getOptType());
		ArrayNode items = JsonNodeFactory.instance.arrayNode();
		for (DuckulaEventItem duckulaEventItem : duckulaEvent.getItemsList()) {
			ObjectNode itemobj = JsonNodeFactory.instance.objectNode();
			switch (duckulaEvent.getOptType()) {
			case update:
				itemobj.putPOJO("after", duckulaEventItem.getAfterMap());
				itemobj.putPOJO("before", duckulaEventItem.getBeforeMap());
				break;
			case insert:
				itemobj.putPOJO("after", duckulaEventItem.getAfterMap());
				break;
			case delete:
				itemobj.putPOJO("before", duckulaEventItem.getBeforeMap());
				break;
			default:
				break;
			}
			items.add(itemobj);
		}
		retobj.set("items", items);
		return retobj;
	}

	/**
	 * 通过duckula数据反推得到附加字段,
	 * 
	 * @param duckulaEvent
	 * @return
	 */
	public static Map getAddColValues(DuckulaEvent duckulaEvent,
			AddColNameType addColNameType) {
		Map addValues = null;
		if (addColNameType != AddColNameType.no) {// 组装附加字段
			addValues = new HashMap();
			for (AddColName addColName : AddColName.values()) {
				if ((addColNameType == AddColNameType.selective || addColNameType == AddColNameType.selective_ori)
						&& !addColName.isSetValue()) {// 是敏感没有配置列值
					boolean logicDel = Conf.getBoolean("common.binlog.alone.binlog.global.logicDel").booleanValue();
					if (!logicDel || (addColName != AddColName.lastOpttype && addColName != AddColName.commitTime
							&& addColName != AddColName.isDelete)) {// 不是逻辑删除或逻辑删除是不是lastOpttype和commitTime就跳过
						continue;
					}
				}
				addValues.put(addColName, getAddColValue(duckulaEvent, addColName));
			}
		}
		return addValues;
	}

	public static String getAddColValue(DuckulaEvent duckulaEvent, AddColName addColName) {
		String retvalue = "";
		switch (addColName) {
		case commitTime:
			if (duckulaEvent.getCommitTime() > 0) {// 20220726 对于jdbc插件,如果是long型是没办法入库的
				String tempValue = DateFormatCase.YYYY_MM_DD_hhmmss.getInstanc()
						.format(new Date(duckulaEvent.getCommitTime()));
				retvalue = tempValue;
			}
			break;
		case dumpTime:
			if (duckulaEvent.getDumpTime() > 0) {// 20220726 对于jdbc插件,如果是long型是没办法入库的
				String tempValue = DateFormatCase.YYYY_MM_DD_hhmmss.getInstanc()
						.format(new Date(duckulaEvent.getDumpTime()));
				retvalue = tempValue;
			}
			break;
		case isDelete:
			retvalue = !isAfter(duckulaEvent.getOptType()) ? "1" : "0";
			break;
		case lastOpttype:
			retvalue = duckulaEvent.getOptType().name();
			break;
		case oriDb:
			retvalue = duckulaEvent.getDb();
			break;
		case oriTb:
			retvalue = duckulaEvent.getTb();
			break;
		case oriInstid:
			retvalue = String.valueOf(duckulaEvent.getDbInstanceId());
			break;
		default:
			break;
		}
		return retvalue;
	}

	/***
	 * 得到update类型的before值,有些对冲逻辑会有需要。
	 * 
	 * @param duckulaEvent
	 * @param index
	 * @return
	 */
	public static ObjectNode getChangedUpdateBefore(DuckulaEvent duckulaEvent, int index) {
		if (duckulaEvent.getOptType() == OptType.update && duckulaEvent.getItemsCount() >= index + 1
				&& MapUtils.isNotEmpty(duckulaEvent.getItems(index).getBeforeMap())) {
			ObjectNode retjson = JsonNodeFactory.instance.objectNode();
			Map beforeMap = duckulaEvent.getItems(index).getBeforeMap();
			Map afterMap = duckulaEvent.getItems(index).getAfterMap();
			for (String colName : duckulaEvent.getColsList()) {// 都是业务字段,没有附加字段
				// 排除附加字段的
//				AddColName addColName = AddColName.findByColName(colName);
//				if(addColName!=null) {
//					continue;
//				}

				if (!beforeMap.containsKey(colName) && !afterMap.containsKey(colName)) {
					// 都为空表示相等,不处理
				} else if (beforeMap.containsKey(colName) && !afterMap.containsKey(colName)) {
					retjson.set(colName, DuckulaAssit.getValue(duckulaEvent, index, colName));
				} else if (!beforeMap.containsKey(colName) && afterMap.containsKey(colName)) {// after新增,这块,本方法不处理。
					retjson.set(colName, null);
				} else {
					String beforeValue = beforeMap.get(colName);
					String afterValue = afterMap.get(colName);
					if (!beforeValue.equals(afterValue)) {
						retjson.set(colName, DuckulaAssit.getValueBefore(duckulaEvent, index, colName));// 20230213把before放到json
					}
				}
			}
			return retjson;
		}
		return null;
	}

	public static Map getAddColValuesStr(Map addValues,
			FieldFormart fieldFormart) {
		Map retmap = new HashMap();
		for (AddColName addColName : addValues.keySet()) {
			String value = null;
			// 值已做过处理,所以这里不需要处理了。
//			if (AddColName.commitTime == addColName || AddColName.dumpTime == addColName) {
//				// 使用TyyyyMMddHHmmss导致大了8个小时的问题,改为一般时间。20220708
//				value = DateFormatCase.YYYY_MM_DD_hhmmss.getInstanc().format(addValues.get(addColName));
//			} else {
			value = String.valueOf(addValues.get(addColName));
//			}
			retmap.put(addColName.getColNameTrue(fieldFormart), value);
		}
		return retmap;
	}

	public static Map getAddColValuesStr(DuckulaEvent duckulaEvent, AddColNameType addColNameType,
			FieldFormart fieldFormart) {
		return getAddColValuesStr(getAddColValues(duckulaEvent, addColNameType), fieldFormart);
	}

	/***
	 * 得到mysql的当前位点
	 * 
	 * @param conn 数据库连接
	 * @return
	 */
	public static Position.Builder getMastStatus(Connection conn) {
		ResultSet rs = JdbcAssit.querySql(conn, "show master status");
		try {
			if (rs.next()) {
				String filename = rs.getString(1);
				long pos = rs.getLong(2);
				Position.Builder ret = Position.newBuilder();
				ret.setFileName(filename);
				ret.setPos(pos);
				if (rs.getMetaData().getColumnCount() >= 5) {
					String gtidStr = rs.getString(5);
					ret.setGtids(gtidStr.replace("/n", ""));
				}
				rs = JdbcAssit.querySql(conn, "show variables like 'server_id'");
				if (rs.next()) {
					long masterServerId = rs.getLong(2);
					ret.setMasterServerId(masterServerId);
				}
				rs = JdbcAssit.querySql(conn, "SELECT unix_timestamp(now())");// 得到时间戳,单位为秒
				if (rs.next()) {
					long time = rs.getLong(1) * 1000;
					ret.setTime(time);
					ret.setTimeStr(DateFormatCase.YYYY_MM_DD_hhmmss.getInstanc().format(time));
				}
				// 20200817 缺少serverip和clientid问题修复
				// ret.setServerIp(connConfBuilder.getHost());
				// ret.setClintId(connConfBuilder.getClientId());
				return ret;
			}
			throw new RuntimeException("没有得到mastStatus,服务器不支持binlog");
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy