mirror of https://github.com/apache/iotdb
add QP
This commit is contained in:
parent
22a454e424
commit
2357155022
6
pom.xml
6
pom.xml
|
@ -37,6 +37,12 @@
|
|||
<version>${hadoop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>10.12.1.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.Role;
|
||||
import cn.edu.thu.tsfiledb.auth.model.RolePermission;
|
||||
import cn.edu.thu.tsfiledb.auth.model.User;
|
||||
import cn.edu.thu.tsfiledb.auth.model.UserPermission;
|
||||
import cn.edu.thu.tsfiledb.auth.model.UserRoleRel;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class AuthDao {
|
||||
|
||||
/**
|
||||
* if the user don't exist in the db, return true else return false
|
||||
*
|
||||
* @param statement
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public boolean addUser(Statement statement, User user) {
|
||||
UserDao dao = new UserDao();
|
||||
boolean state = false;
|
||||
// Check the user exist or not
|
||||
if (dao.getUser(statement, user.getUserName()) == null) {
|
||||
dao.createUser(statement, user);
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* if the role isn't exist in the db, will return true else return false
|
||||
*
|
||||
* @param statement
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
public boolean addRole(Statement statement, Role role) {
|
||||
RoleDao dao = new RoleDao();
|
||||
boolean state = false;
|
||||
// check the user exist or not
|
||||
if (dao.getRole(statement, role.getRoleName()) == null) {
|
||||
dao.createRole(statement, role);
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* the user and role is exist, the relation is not exist, will return true
|
||||
* else return false
|
||||
*
|
||||
* @param statement
|
||||
* @param userName
|
||||
* @param roleName
|
||||
* @return
|
||||
*/
|
||||
public boolean addUserRoleRel(Statement statement, String userName, String roleName) {
|
||||
UserDao userDao = new UserDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
int userId;
|
||||
int roleId;
|
||||
User user = null;
|
||||
Role role = null;
|
||||
boolean state = false;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
userId = user.getId();
|
||||
roleId = role.getId();
|
||||
UserRoleRel userRoleRel = new UserRoleRel(userId, roleId);
|
||||
|
||||
if (userRoleRelDao.getUserRoleRel(statement, userRoleRel) == null) {
|
||||
state = true;
|
||||
userRoleRelDao.createUserRoleRel(statement, userRoleRel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean addUserPermission(Statement statement, String userName, String nodeName, int permissionId) {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
boolean state = false;
|
||||
User user = null;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
int userId = user.getId();
|
||||
UserPermission userPermission = new UserPermission(userId, nodeName, permissionId);
|
||||
if (userPermissionDao.getUserPermission(statement, userPermission) == null) {
|
||||
state = true;
|
||||
userPermissionDao.createUserPermission(statement, userPermission);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean addRolePermission(Statement statement, String roleName, String nodeName, int permissionId) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
boolean state = false;
|
||||
Role role = null;
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
int roleId = role.getId();
|
||||
RolePermission rolePermission = new RolePermission(roleId, nodeName, permissionId);
|
||||
if (rolePermissionDao.getRolePermission(statement, rolePermission) == null) {
|
||||
state = true;
|
||||
rolePermissionDao.createRolePermission(statement, rolePermission);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUser(Statement statement, String userName) {
|
||||
UserDao userDao = new UserDao();
|
||||
boolean state = false;
|
||||
if (userDao.deleteUser(statement, userName) > 0) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteRole(Statement statement, String roleName) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
boolean state = false;
|
||||
if (roleDao.deleteRole(statement, roleName) > 0) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUserRoleRel(Statement statement, String userName, String roleName) {
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
UserDao userDao = new UserDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
int userId;
|
||||
int roleId;
|
||||
User user = null;
|
||||
Role role = null;
|
||||
boolean state = false;
|
||||
|
||||
if ((user = userDao.getUser(statement, userName)) != null
|
||||
&& (role = roleDao.getRole(statement, roleName)) != null) {
|
||||
userId = user.getId();
|
||||
roleId = role.getId();
|
||||
UserRoleRel userRoleRel = new UserRoleRel(userId, roleId);
|
||||
if (userRoleRelDao.deleteUserRoleRel(statement, userRoleRel) > 0) {
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUserPermission(Statement statement, String userName, String nodeName, int permissionId) {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
int userId;
|
||||
User user = null;
|
||||
boolean state = false;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
userId = user.getId();
|
||||
UserPermission userPermission = new UserPermission(userId, nodeName, permissionId);
|
||||
if (userPermissionDao.deleteUserPermission(statement, userPermission) > 0) {
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteRolePermission(Statement statement, String roleName, String nodeName, int permissionId) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
Role role = null;
|
||||
int roleId;
|
||||
boolean state = false;
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
roleId = role.getId();
|
||||
RolePermission rolePermission = new RolePermission(roleId, nodeName, permissionId);
|
||||
if (rolePermissionDao.deleteRolePermission(statement, rolePermission) > 0) {
|
||||
state = true;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// 如果username或者nodename不存在怎么办?
|
||||
public List<User> getUsers(Statement statement) {
|
||||
UserDao userDao = new UserDao();
|
||||
List<User> users = userDao.getUsers(statement);
|
||||
return users;
|
||||
}
|
||||
|
||||
public List<Role> getRoles(Statement statement) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
List<Role> roles = roleDao.getRoles(statement);
|
||||
return roles;
|
||||
}
|
||||
|
||||
public List<UserRoleRel> getAllUserRoleRel(Statement statement) {
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
List<UserRoleRel> userRoleRels = userRoleRelDao.getUserRoleRels(statement);
|
||||
return userRoleRels;
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回值的问题
|
||||
*/
|
||||
public List<Role> getRolesByUser(Statement statement, String userName) {
|
||||
UserDao userDao = new UserDao();
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
// 当 user不存在的情况下是返回 size = 0,还是 null
|
||||
ArrayList<Role> roles = new ArrayList<>();
|
||||
User user = userDao.getUser(statement, userName);
|
||||
if (user != null) {
|
||||
int userId = user.getId();
|
||||
List<UserRoleRel> userRoleRels = userRoleRelDao.getUserRoleRelByUser(statement, userId);
|
||||
for (UserRoleRel userRoleRel : userRoleRels) {
|
||||
int roleId = userRoleRel.getRoleId();
|
||||
Role role = roleDao.getRole(statement, roleId);
|
||||
roles.add(role);
|
||||
}
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回值的问题
|
||||
*/
|
||||
public List<UserPermission> getUserPermission(Statement statement, String userName, String nodeName) {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
List<UserPermission> userPermissions = new ArrayList<>();
|
||||
// 当user 不存在的时候 是返回size = 0,还是null
|
||||
User user = userDao.getUser(statement, userName);
|
||||
if (user != null) {
|
||||
userPermissions = userPermissionDao.getUserPermissionByUserAndNodeName(statement, user.getId(), nodeName);
|
||||
}
|
||||
// 返回值可能是null还是 没有结果 size = 0;
|
||||
return userPermissions;
|
||||
}
|
||||
|
||||
public List<RolePermission> getRolePermission(Statement statement, String roleName, String nodeName) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
List<RolePermission> rolePermissions = new ArrayList<>();
|
||||
Role role = roleDao.getRole(statement, roleName);
|
||||
if (role != null) {
|
||||
rolePermissions = rolePermissionDao.getRolePermissionByRoleAndNodeName(statement, role.getId(), nodeName);
|
||||
}
|
||||
return rolePermissions;
|
||||
}
|
||||
|
||||
/*
|
||||
* All user's permission: userPermission and rolePermission
|
||||
*/
|
||||
public Set<Integer> getAllUserPermission(Statement statement, String userName, String nodeName) {
|
||||
// permission set
|
||||
Set<Integer> permissionSet = new HashSet<>();
|
||||
// userpermission
|
||||
List<UserPermission> userPermissions = getUserPermission(statement, userName, nodeName);
|
||||
for (UserPermission userPermission : userPermissions) {
|
||||
permissionSet.add(userPermission.getPermissionId());
|
||||
}
|
||||
// rolepermission
|
||||
List<Role> roles = getRolesByUser(statement, userName);
|
||||
for (Role role : roles) {
|
||||
List<RolePermission> rolePermissions = getRolePermission(statement, role.getRoleName(), nodeName);
|
||||
// operation add the permission into the set
|
||||
for (RolePermission rolePermission : rolePermissions) {
|
||||
permissionSet.add(rolePermission.getPermissionId());
|
||||
}
|
||||
}
|
||||
return permissionSet;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.*;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*/
|
||||
public class AuthDaoWrap {
|
||||
|
||||
// Must init the DBdao before use this class
|
||||
private Statement statement = DBdao.getStatement();
|
||||
|
||||
|
||||
public boolean addUser(User user) {
|
||||
UserDao dao = new UserDao();
|
||||
boolean state = false;
|
||||
// Check the user exist or not
|
||||
if (dao.getUser(statement, user.getUserName()) == null) {
|
||||
dao.createUser(statement, user);
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public boolean addRole(Role role) {
|
||||
RoleDao dao = new RoleDao();
|
||||
boolean state = false;
|
||||
// check the user exist or not
|
||||
if (dao.getRole(statement, role.getRoleName()) == null) {
|
||||
dao.createRole(statement, role);
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public boolean addUserRoleRel(String userName, String roleName) throws AuthException {
|
||||
UserDao userDao = new UserDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
int userId;
|
||||
int roleId;
|
||||
User user = null;
|
||||
Role role = null;
|
||||
boolean state = false;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
userId = user.getId();
|
||||
roleId = role.getId();
|
||||
UserRoleRel userRoleRel = new UserRoleRel(userId, roleId);
|
||||
|
||||
if (userRoleRelDao.getUserRoleRel(statement, userRoleRel) == null) {
|
||||
state = true;
|
||||
userRoleRelDao.createUserRoleRel(statement, userRoleRel);
|
||||
} else {
|
||||
throw new AuthException(String.format("The user of %s already has the role of %s", userName, role.getRoleName()));
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The role is not exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean addUserPermission(String userName, String nodeName, int permissionId) throws AuthException {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
boolean state = false;
|
||||
User user = null;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
int userId = user.getId();
|
||||
UserPermission userPermission = new UserPermission(userId, nodeName, permissionId);
|
||||
if (userPermissionDao.getUserPermission(statement, userPermission) == null) {
|
||||
state = true;
|
||||
userPermissionDao.createUserPermission(statement, userPermission);
|
||||
} else {
|
||||
throw new AuthException("The permission is exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean addRolePermission(String roleName, String nodeName, int permissionId) throws AuthException {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
boolean state = false;
|
||||
Role role = null;
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
int roleId = role.getId();
|
||||
RolePermission rolePermission = new RolePermission(roleId, nodeName, permissionId);
|
||||
if (rolePermissionDao.getRolePermission(statement, rolePermission) == null) {
|
||||
state = true;
|
||||
rolePermissionDao.createRolePermission(statement, rolePermission);
|
||||
} else {
|
||||
throw new AuthException("The permission is exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The role is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUser(String userName) {
|
||||
UserDao userDao = new UserDao();
|
||||
boolean state = false;
|
||||
if (userDao.deleteUser(statement, userName) > 0) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteRole(String roleName) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
boolean state = false;
|
||||
if (roleDao.deleteRole(statement, roleName) > 0) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUserRoleRel(String userName, String roleName) throws AuthException {
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
UserDao userDao = new UserDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
int userId;
|
||||
int roleId;
|
||||
User user = null;
|
||||
Role role = null;
|
||||
boolean state = false;
|
||||
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
userId = user.getId();
|
||||
roleId = role.getId();
|
||||
UserRoleRel userRoleRel = new UserRoleRel(userId, roleId);
|
||||
if (userRoleRelDao.deleteUserRoleRel(statement, userRoleRel) > 0) {
|
||||
state = true;
|
||||
} else {
|
||||
throw new AuthException(String.format("The user of %s does not have the role of %s"), userName, role.getRoleName());
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The role is not exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteUserPermission(String userName, String nodeName, int permissionId) throws AuthException {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
int userId;
|
||||
User user = null;
|
||||
boolean state = false;
|
||||
if ((user = userDao.getUser(statement, userName)) != null) {
|
||||
userId = user.getId();
|
||||
UserPermission userPermission = new UserPermission(userId, nodeName, permissionId);
|
||||
if (userPermissionDao.deleteUserPermission(statement, userPermission) > 0) {
|
||||
state = true;
|
||||
} else {
|
||||
throw new AuthException("The permission is not exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean deleteRolePermission(String roleName, String nodeName, int permissionId) throws AuthException {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
Role role = null;
|
||||
int roleId;
|
||||
boolean state = false;
|
||||
if ((role = roleDao.getRole(statement, roleName)) != null) {
|
||||
roleId = role.getId();
|
||||
RolePermission rolePermission = new RolePermission(roleId, nodeName, permissionId);
|
||||
if (rolePermissionDao.deleteRolePermission(statement, rolePermission) > 0) {
|
||||
state = true;
|
||||
} else {
|
||||
throw new AuthException("The permission is not exist");
|
||||
}
|
||||
} else {
|
||||
throw new AuthException("The role is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public User getUser(String userName, String password) {
|
||||
UserDao userDao = new UserDao();
|
||||
User user = null;
|
||||
user = userDao.getUser(statement, userName, password);
|
||||
return user;
|
||||
}
|
||||
|
||||
public User getUser(String userName) {
|
||||
UserDao userDao = new UserDao();
|
||||
User user = null;
|
||||
user = userDao.getUser(statement, userName);
|
||||
return user;
|
||||
}
|
||||
|
||||
// 如果username或者nodename不存在怎么办?
|
||||
public List<User> getUsers() {
|
||||
UserDao userDao = new UserDao();
|
||||
List<User> users = userDao.getUsers(statement);
|
||||
return users;
|
||||
}
|
||||
|
||||
public List<Role> getRoles() {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
List<Role> roles = roleDao.getRoles(statement);
|
||||
return roles;
|
||||
}
|
||||
|
||||
public List<UserRoleRel> getAllUserRoleRel() {
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
List<UserRoleRel> userRoleRels = userRoleRelDao.getUserRoleRels(statement);
|
||||
return userRoleRels;
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回值的问题
|
||||
*/
|
||||
public List<Role> getRolesByUser(String userName) {
|
||||
UserDao userDao = new UserDao();
|
||||
UserRoleRelDao userRoleRelDao = new UserRoleRelDao();
|
||||
RoleDao roleDao = new RoleDao();
|
||||
// 当 user不存在的情况下是返回 size = 0,还是 null
|
||||
ArrayList<Role> roles = new ArrayList<>();
|
||||
User user = userDao.getUser(statement, userName);
|
||||
if (user != null) {
|
||||
int userId = user.getId();
|
||||
List<UserRoleRel> userRoleRels = userRoleRelDao.getUserRoleRelByUser(statement, userId);
|
||||
for (UserRoleRel userRoleRel : userRoleRels) {
|
||||
int roleId = userRoleRel.getRoleId();
|
||||
Role role = roleDao.getRole(statement, roleId);
|
||||
roles.add(role);
|
||||
}
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
public UserPermission getUserPermission(String userName, String nodeName, int permissionId) {
|
||||
UserPermission userPermission = null;
|
||||
UserDao userDao = new UserDao();
|
||||
User user = userDao.getUser(statement, userName);
|
||||
if (user != null) {
|
||||
int userId = user.getId();
|
||||
userPermission = new UserPermission(userId, nodeName, permissionId);
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
// userPermission will be null
|
||||
userPermission = userPermissionDao.getUserPermission(statement, userPermission);
|
||||
}
|
||||
return userPermission;
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回值的问题
|
||||
*/
|
||||
public List<UserPermission> getUserPermissions(String userName, String nodeName) throws AuthException {
|
||||
UserDao userDao = new UserDao();
|
||||
UserPermissionDao userPermissionDao = new UserPermissionDao();
|
||||
List<UserPermission> userPermissions = new ArrayList<>();
|
||||
// 当user 不存在的时候 是返回size = 0,还是null
|
||||
User user = userDao.getUser(statement, userName);
|
||||
if (user != null) {
|
||||
userPermissions = userPermissionDao.getUserPermissionByUserAndNodeName(statement, user.getId(), nodeName);
|
||||
} else {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
// 返回值可能是null还是 没有结果 size = 0;
|
||||
return userPermissions;
|
||||
}
|
||||
|
||||
public List<RolePermission> getRolePermissions(String roleName, String nodeName) {
|
||||
RoleDao roleDao = new RoleDao();
|
||||
RolePermissionDao rolePermissionDao = new RolePermissionDao();
|
||||
List<RolePermission> rolePermissions = new ArrayList<>();
|
||||
Role role = roleDao.getRole(statement, roleName);
|
||||
if (role != null) {
|
||||
rolePermissions = rolePermissionDao.getRolePermissionByRoleAndNodeName(statement, role.getId(), nodeName);
|
||||
}
|
||||
return rolePermissions;
|
||||
}
|
||||
|
||||
/*
|
||||
* All user's permission: userPermission and rolePermission
|
||||
*/
|
||||
public Set<Integer> getAllUserPermissions(String userName, String nodeName) throws AuthException {
|
||||
// permission set
|
||||
Set<Integer> permissionSet = new HashSet<>();
|
||||
// userpermission
|
||||
List<UserPermission> userPermissions = getUserPermissions(userName, nodeName);
|
||||
for (UserPermission userPermission : userPermissions) {
|
||||
permissionSet.add(userPermission.getPermissionId());
|
||||
}
|
||||
// rolepermission
|
||||
List<Role> roles = getRolesByUser(userName);
|
||||
for (Role role : roles) {
|
||||
List<RolePermission> rolePermissions = getRolePermissions(role.getRoleName(), nodeName);
|
||||
// operation add the permission into the set
|
||||
for (RolePermission rolePermission : rolePermissions) {
|
||||
permissionSet.add(rolePermission.getPermissionId());
|
||||
}
|
||||
}
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
public boolean updateUserPassword(String userName, String newPassword) {
|
||||
boolean state = false;
|
||||
UserDao userDao = new UserDao();
|
||||
int change = userDao.updateUserPassword(statement, userName, newPassword);
|
||||
if (change > 0) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean checkUserPermission(String userName, String nodeName, int permissionId) {
|
||||
boolean state = false;
|
||||
UserPermission userPermission = this.getUserPermission(userName, nodeName, permissionId);
|
||||
if (userPermission != null) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// add the method without the authdao
|
||||
public boolean checkUser(String userName, String password) {
|
||||
boolean state = false;
|
||||
User user = this.getUser(userName, password);
|
||||
if (user != null) {
|
||||
state = true;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.AuthException;
|
||||
import cn.edu.thu.tsfiledb.auth.model.Role;
|
||||
import cn.edu.thu.tsfiledb.auth.model.User;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*/
|
||||
public class Authorizer {
|
||||
|
||||
private static AuthDaoWrap authDaoWrap = new AuthDaoWrap();
|
||||
|
||||
/**
|
||||
* Check the information for login
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @return
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static synchronized boolean login(String username, String password) throws AuthException {
|
||||
|
||||
boolean state = false;
|
||||
state = authDaoWrap.checkUser(username, password);
|
||||
if (state == false) {
|
||||
throw new AuthException("The username or the password is not correct");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add user
|
||||
*
|
||||
* @param username is not null or empty
|
||||
* @param password is not null or empty
|
||||
* @return true: add user successfully, false: add user unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean createUser(String username, String password) throws AuthException {
|
||||
boolean state = false;
|
||||
User user = new User(username, password);
|
||||
if (username == null || password == null || "".equals(username) || "".equals(password)) {
|
||||
throw new AuthException("Username or password can't be empty");
|
||||
}
|
||||
state = authDaoWrap.addUser(user);
|
||||
if (state == false) {
|
||||
throw new AuthException("The user is exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user
|
||||
*
|
||||
* @param username
|
||||
* @return true: delete user successfully, false: delete user unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean deleteUser(String username) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.deleteUser(username);
|
||||
if (state == false) {
|
||||
throw new AuthException("The user is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add permission to user
|
||||
*
|
||||
* @param username
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
* @return true: add permission successfully, false: add permission unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean addPmsToUser(String username, String nodeName, int permissionId) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.addUserPermission(username, nodeName, permissionId);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permission from user
|
||||
*
|
||||
* @param userName
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
* @return true: delete permission from user successfully, false: delete permission from user unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean removePmsFromUser(String userName, String nodeName, int permissionId) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.deleteUserPermission(userName, nodeName, permissionId);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role
|
||||
*
|
||||
* @param roleName
|
||||
* @return true: add role successfully, false: add role unsuccessfully
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean createRole(String roleName) throws AuthException {
|
||||
boolean state = false;
|
||||
Role role = new Role(roleName);
|
||||
state = authDaoWrap.addRole(role);
|
||||
if (state == false) {
|
||||
throw new AuthException("The role is exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role
|
||||
*
|
||||
* @param roleName
|
||||
* @return true: delete role successfully, false: delete role unsuccessfully
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean deleteRole(String roleName) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.deleteRole(roleName);
|
||||
if (state == false) {
|
||||
throw new AuthException("The role is not exist");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add permission to role
|
||||
*
|
||||
* @param roleName
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
* @return true: add permission to role successfully, false: add permission to role unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean addPmsToRole(String roleName, String nodeName, int permissionId) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.addRolePermission(roleName, nodeName, permissionId);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete permission from role
|
||||
*
|
||||
* @param roleName
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
* @return true: delete permission from role successfully, false: delete permission from role unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean removePmsFromRole(String roleName, String nodeName, int permissionId) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.deleteRolePermission(roleName, nodeName, permissionId);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role to user
|
||||
*
|
||||
* @param roleName
|
||||
* @param username
|
||||
* @return true: add role to user successfully, false: add role to user unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean grantRoleToUser(String roleName, String username) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.addUserRoleRel(username, roleName);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete role from user
|
||||
*
|
||||
* @param roleName
|
||||
* @param username
|
||||
* @return true: delete role from user successfully, false: delete role from user unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean revokeRoleFromUser(String roleName, String username) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.deleteUserRoleRel(username, roleName);
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the all permission of the user
|
||||
*
|
||||
* @param username
|
||||
* @param nodeName
|
||||
* @return
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static Set<Integer> getPermission(String username, String nodeName) throws AuthException {
|
||||
Set<Integer> permissionSets = null;
|
||||
permissionSets = authDaoWrap.getAllUserPermissions(username, nodeName);
|
||||
return permissionSets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the password
|
||||
*
|
||||
* @param username
|
||||
* @param oldPassword
|
||||
* @param newPassword
|
||||
* @return true: update the password successfully, false: update the password unsuccessfully
|
||||
* @throws AuthException
|
||||
*/
|
||||
public static boolean updateUserPassword(String username, String newPassword) throws AuthException {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.updateUserPassword(username, newPassword);
|
||||
if (state == false) {
|
||||
throw new AuthException("The username or the password is not correct");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the permission belong to the user
|
||||
*
|
||||
* @param username
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
* @return true: the user has this permission, false: the user does not have the permission
|
||||
*/
|
||||
public static boolean checkUserPermission(String username, String nodeName, int permissionId) {
|
||||
boolean state = false;
|
||||
state = authDaoWrap.checkUserPermission(username, nodeName, permissionId);
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import cn.edu.thu.tsfile.common.conf.TSFileDescriptor;
|
||||
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class DBdao {
|
||||
|
||||
private String derbyEmbeddedDriver = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
private String protocal = "jdbc:derby:";
|
||||
private String DBName;
|
||||
private String createOrNot = ";create=true";
|
||||
private String shutdown = ";shutdown=True";
|
||||
|
||||
private static Connection connection = null;
|
||||
private static Statement statement = null;
|
||||
private PreparedStatement preparedStatement = null;
|
||||
|
||||
/**
|
||||
* @param dBName
|
||||
*/
|
||||
public DBdao(String dBName) {
|
||||
String path = TSFileDescriptor.getInstance().getConfig().derbyHome + File.separator + dBName;
|
||||
DBName = path;
|
||||
}
|
||||
|
||||
public DBdao() {
|
||||
this("derby-tsfile-db");
|
||||
}
|
||||
|
||||
private void initDriver() {
|
||||
try {
|
||||
Class.forName(derbyEmbeddedDriver).newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void connection() {
|
||||
String url = protocal + DBName + createOrNot;
|
||||
try {
|
||||
connection = DriverManager.getConnection(url);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeConnection() {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
throw new Exception("The connection is null");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void statement() {
|
||||
try {
|
||||
statement = connection.createStatement();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeStatement() {
|
||||
if (statement != null) {
|
||||
try {
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
throw new Exception("The statement is null");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkTableExist() {
|
||||
boolean state = false;
|
||||
|
||||
try {
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
ResultSet resultSet;
|
||||
resultSet = metaData.getTables(null, "APP", "USERTABLE", null);
|
||||
if (resultSet.next()) {
|
||||
state = true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// create table;
|
||||
public boolean createOriTable() {
|
||||
boolean state = false;
|
||||
try {
|
||||
statement.executeUpdate(InitTable.createTableSql);
|
||||
statement.executeUpdate(InitTable.createRoleTableSql);
|
||||
statement.executeUpdate(InitTable.createUserRoleRelTableSql);
|
||||
statement.executeUpdate(InitTable.creteUserPermissionTableSql);
|
||||
statement.executeUpdate(InitTable.createRolePermissionTableSql);
|
||||
statement.executeUpdate(InitTable.insertIntoUserToTableSql);
|
||||
state = true;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public void getPreparedStatement() {
|
||||
try {
|
||||
preparedStatement = connection.prepareStatement("test");
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void closePreparedStatement() {
|
||||
|
||||
}
|
||||
|
||||
public void open() {
|
||||
initDriver();
|
||||
connection();
|
||||
statement();
|
||||
if (!checkTableExist()) {
|
||||
//
|
||||
createOriTable();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closeStatement();
|
||||
closeConnection();
|
||||
// try {
|
||||
// DriverManager.getConnection(protocal + shutdown);
|
||||
// } catch (SQLException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
public static Statement getStatement() {
|
||||
return statement;
|
||||
}
|
||||
|
||||
public static Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class InitTable {
|
||||
|
||||
public static String createTableSql = "create table userTable("
|
||||
+ "id INT generated always as identity(start with 1,increment by 1) not null primary key,"
|
||||
+ "userName VARCHAR(20) not null unique," + "password VARCHAR(20) not null,"
|
||||
+ "locked CHAR(1) check (locked='t' or locked='f')," + "validTime VARCHAR(20))";
|
||||
|
||||
public static String createRoleTableSql = "create table roleTable("
|
||||
+ "id INT generated always as identity(start with 1, increment by 1) not null primary key,"
|
||||
+ "roleName VARCHAR(20) not null unique)";
|
||||
|
||||
public static String createUserRoleRelTableSql = "create table userRoleRelTable("
|
||||
+ "id INT generated always as identity(start with 1, increment by 1) ," + "userId INT," + "roleId INT,"
|
||||
+ "constraint pk_userrolerel primary key (userId,roleId),"
|
||||
+ "foreign key (userId) references usertable(id) on delete cascade,"
|
||||
+ "foreign key (roleId) references roletable(id) on delete cascade)";
|
||||
|
||||
public static String creteUserPermissionTableSql = "create table userPermissionTable("
|
||||
+ "id INT generated always as identity(start with 1,increment by 1) ," + "userId INT not null,"
|
||||
+ "nodeName VARCHAR(20) not null," + "permissionId INT not null,"
|
||||
+ "constraint pk_userpermission primary key (userId,nodeName,permissionId),"
|
||||
+ "foreign key (userId) references usertable(id) on delete cascade)";
|
||||
|
||||
public static String createRolePermissionTableSql = "create table rolePermissionTable("
|
||||
+ "id INT generated always as identity(start with 1, increment by 1)," + "roleId INT not null,"
|
||||
+ "nodeName VARCHAR(20) not null," + "permissionId INT not null,"
|
||||
+ "constraint pk_rolepermission primary key (roleId,nodeName,permissionId),"
|
||||
+ "foreign key (roleId) references roleTable(id) on delete cascade)";
|
||||
|
||||
public static String insertIntoUserToTableSql = "insert into usertable (username,password) values('root','root')";
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.DBContext;
|
||||
import cn.edu.thu.tsfiledb.auth.model.Role;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class RoleDao {
|
||||
|
||||
public List<Role> getRoles(Statement statement) {
|
||||
ArrayList<Role> arrayList = new ArrayList<>();
|
||||
String sql = "select * from " + DBContext.roleTable;
|
||||
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
Role role = new Role();
|
||||
int id = resultSet.getInt(1);
|
||||
String roleName = resultSet.getString(2);
|
||||
role.setId(id);
|
||||
role.setRoleName(roleName);
|
||||
arrayList.add(role);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public Role getRole(Statement statement, String roleName) {
|
||||
String sql = "select * from " + DBContext.roleTable + " where roleName=" + "'" + roleName + "'";
|
||||
Role role = null;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
int id = resultSet.getInt(1);
|
||||
String name = resultSet.getString(2);
|
||||
role = new Role(id, name);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
public Role getRole(Statement statement, int roleId) {
|
||||
String sql = "select * from " + DBContext.roleTable + " where id=" + roleId;
|
||||
Role role = null;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
role = new Role(roleId, resultSet.getString(2));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
public int deleteRole(Statement statement, String roleName) {
|
||||
String sql = "delete from " + DBContext.roleTable + " where roleName=" + "'" + roleName + "'";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int createRole(Statement statement, Role role) {
|
||||
String sql = "insert into " + DBContext.roleTable + " (" + "roleName" + ")" + " values('" + role.getRoleName()
|
||||
+ "')";
|
||||
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int updateRole(Statement statement) {
|
||||
String sql = "update " + DBContext.roleTable + " set ";
|
||||
int state = 0;
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.DBContext;
|
||||
import cn.edu.thu.tsfiledb.auth.model.RolePermission;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class RolePermissionDao {
|
||||
|
||||
public int createRolePermission(Statement statement, RolePermission rolePermission) {
|
||||
String sql = "insert into " + DBContext.rolePermission + " (roleId,nodeName,permissionId) values" + "("
|
||||
+ rolePermission.getRoleId() + ",'" + rolePermission.getNodeName() + "',"
|
||||
+ rolePermission.getPermissionId() + ")";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int deleteRolePermission(Statement statement, RolePermission rolePermission) {
|
||||
String sql = "delete from " + DBContext.rolePermission + " where roleId=" + rolePermission.getRoleId() + " and "
|
||||
+ "nodeName=" + "'" + rolePermission.getNodeName() + "'" + " and " + "permissionId="
|
||||
+ rolePermission.getPermissionId();
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public RolePermission getRolePermission(Statement statement, RolePermission rolePermission) {
|
||||
String sql = "select * from " + DBContext.rolePermission + " where roleId=" + rolePermission.getRoleId()
|
||||
+ " and nodeName='" + rolePermission.getNodeName() + "' and permissionId="
|
||||
+ rolePermission.getPermissionId();
|
||||
RolePermission permission = null;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
permission = new RolePermission(resultSet.getInt(1), resultSet.getInt(2), resultSet.getString(3),
|
||||
resultSet.getInt(4));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return permission;
|
||||
}
|
||||
|
||||
public List<RolePermission> getRolePermissions(Statement statement) {
|
||||
String sql = "select * from " + DBContext.rolePermission;
|
||||
List<RolePermission> rolePermissions = new ArrayList<>();
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
RolePermission rolePermission = new RolePermission(resultSet.getInt(1), resultSet.getInt(2),
|
||||
resultSet.getString(3), resultSet.getInt(4));
|
||||
rolePermissions.add(rolePermission);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rolePermissions;
|
||||
}
|
||||
|
||||
public List<RolePermission> getRolePermissionByRoleAndNodeName(Statement statement, int roleId, String nodeName) {
|
||||
String sql = "select * from " + DBContext.rolePermission + " where roleId=" + roleId + " and nodeName='"
|
||||
+ nodeName + "'";
|
||||
List<RolePermission> rolePermissions = new ArrayList<>();
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
RolePermission rolePermission = new RolePermission(resultSet.getInt(1), resultSet.getInt(2),
|
||||
resultSet.getString(3), resultSet.getInt(4));
|
||||
rolePermissions.add(rolePermission);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rolePermissions;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.DBContext;
|
||||
import cn.edu.thu.tsfiledb.auth.model.User;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class UserDao {
|
||||
|
||||
public int createUser(Statement statement, User user) {
|
||||
|
||||
String sql = "insert into " + DBContext.userTable + " (userName,passWord) " + " values ('" + user.getUserName()
|
||||
+ "','" + user.getPassWord() + "')";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int deleteUser(Statement statement, String userName) {
|
||||
String sql = "delete from " + DBContext.userTable + " where userName=" + "'" + userName + "'";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int updateUserPassword(Statement statement, String userName, String newPassword) {
|
||||
String sql = "update " + DBContext.userTable + " set password='" + newPassword + "'" + " where username='"
|
||||
+ userName + "'";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public List<User> getUsers(Statement statement) {
|
||||
String sql = "select * from " + DBContext.userTable;
|
||||
ArrayList<User> arrayList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
int id = resultSet.getInt(1);
|
||||
String userName = resultSet.getString(2);
|
||||
String passWord = resultSet.getString(3);
|
||||
boolean isLock = resultSet.getBoolean(4);
|
||||
String validTime = resultSet.getString(5);
|
||||
User user = new User(id, userName, passWord, isLock, validTime);
|
||||
arrayList.add(user);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public User getUser(Statement statement, String userName) {
|
||||
String sql = "select * from " + DBContext.userTable + " where userName=" + "'" + userName + "'";
|
||||
User user = null;
|
||||
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
int id = resultSet.getInt(1);
|
||||
String name = userName;
|
||||
String passWord = resultSet.getString(3);
|
||||
boolean isLock = resultSet.getBoolean(4);
|
||||
String validTime = resultSet.getString(5);
|
||||
user = new User(id, name, passWord, isLock, validTime);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
public User getUser(Statement statement, String userName, String password) {
|
||||
User user = null;
|
||||
String sql = "select * from " + DBContext.userTable + " where username='" + userName + "'" + " and password='"
|
||||
+ password + "'";
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
user = new User();
|
||||
user.setId(resultSet.getInt(1));
|
||||
user.setUserName(resultSet.getString(2));
|
||||
user.setPassWord(resultSet.getString(3));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.DBContext;
|
||||
import cn.edu.thu.tsfiledb.auth.model.UserPermission;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class UserPermissionDao {
|
||||
|
||||
public int createUserPermission(Statement statement, UserPermission userPermission) {
|
||||
String sql = "insert into " + DBContext.userPermission + " (userId,nodeName,permissionId)" + " values("
|
||||
+ userPermission.getUserId() + ",'" + userPermission.getNodeName() + "',"
|
||||
+ userPermission.getPermissionId() + ")";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int deleteUserPermission(Statement statement, UserPermission userPermission) {
|
||||
String sql = "delete from " + DBContext.userPermission + " where userId=" + userPermission.getUserId() + " and "
|
||||
+ "nodeName=" + "'" + userPermission.getNodeName() + "'" + " and " + "permissionId="
|
||||
+ userPermission.getPermissionId();
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public UserPermission getUserPermission(Statement statement, UserPermission userPermission) {
|
||||
String sql = "select * from " + DBContext.userPermission + " where userId=" + userPermission.getUserId()
|
||||
+ " and " + "nodeName=" + "'" + userPermission.getNodeName() + "'" + " and " + "permissionId="
|
||||
+ userPermission.getPermissionId();
|
||||
UserPermission permission = null;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
permission = new UserPermission(resultSet.getInt(1), resultSet.getInt(2), resultSet.getString(3),
|
||||
resultSet.getInt(4));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return permission;
|
||||
}
|
||||
|
||||
//
|
||||
public ArrayList<UserPermission> getUserPermissionByUserAndNodeName(Statement statement, int userId,
|
||||
String nodeName) {
|
||||
ArrayList<UserPermission> userPermissions = new ArrayList<>();
|
||||
String sql = "select * from " + DBContext.userPermission + " where userId=" + userId + " and " + "nodeName="
|
||||
+ "'" + nodeName + "'";
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
UserPermission userPermission = new UserPermission(resultSet.getInt(1), resultSet.getInt(2),
|
||||
resultSet.getString(3), resultSet.getInt(4));
|
||||
userPermissions.add(userPermission);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return userPermissions;
|
||||
}
|
||||
|
||||
public List<UserPermission> getUserPermissions(Statement statement) {
|
||||
ArrayList<UserPermission> userPermissions = new ArrayList<>();
|
||||
String sql = "select * from " + DBContext.userPermission;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
UserPermission userPermission = new UserPermission(resultSet.getInt(1), resultSet.getInt(2),
|
||||
resultSet.getString(3), resultSet.getInt(4));
|
||||
userPermissions.add(userPermission);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return userPermissions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package cn.edu.thu.tsfiledb.auth.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.auth.model.DBContext;
|
||||
import cn.edu.thu.tsfiledb.auth.model.UserRoleRel;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class UserRoleRelDao {
|
||||
|
||||
public List<UserRoleRel> getUserRoleRels(Statement statement) {
|
||||
String sql = "select * from " + DBContext.userRoleRel;
|
||||
ArrayList<UserRoleRel> arrayList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
|
||||
int id = resultSet.getInt(1);
|
||||
int userId = resultSet.getInt(2);
|
||||
int roleId = resultSet.getInt(3);
|
||||
UserRoleRel rel = new UserRoleRel(id, userId, roleId);
|
||||
arrayList.add(rel);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public UserRoleRel getUserRoleRel(Statement statement, UserRoleRel rel) {
|
||||
String sql = "select * from " + DBContext.userRoleRel + " where userId=" + rel.getUserId() + " and roleId="
|
||||
+ rel.getRoleId();
|
||||
UserRoleRel userRoleRel = null;
|
||||
ResultSet resultSet;
|
||||
try {
|
||||
resultSet = statement.executeQuery(sql);
|
||||
if (resultSet.next()) {
|
||||
userRoleRel = new UserRoleRel(resultSet.getInt(1), resultSet.getInt(2), resultSet.getInt(3));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return userRoleRel;
|
||||
|
||||
}
|
||||
|
||||
public List<UserRoleRel> getUserRoleRelByUser(Statement statement, int userId) {
|
||||
String sql = "select * from " + DBContext.userRoleRel + " where userId = " + userId;
|
||||
ArrayList<UserRoleRel> arrayList = new ArrayList<>();
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
int id = resultSet.getInt(1);
|
||||
int roleId = resultSet.getInt(3);
|
||||
UserRoleRel rel = new UserRoleRel(id, userId, roleId);
|
||||
arrayList.add(rel);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public List<UserRoleRel> getUserRoleRelByRole(Statement statement, int roleId) {
|
||||
String sql = "select * from " + DBContext.userRoleRel + " where roleId=" + roleId;
|
||||
ArrayList<UserRoleRel> arrayList = new ArrayList<>();
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
while (resultSet.next()) {
|
||||
int id = resultSet.getInt(1);
|
||||
int userId = resultSet.getInt(2);
|
||||
UserRoleRel rel = new UserRoleRel(id, userId, roleId);
|
||||
arrayList.add(rel);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public int createUserRoleRel(Statement statement, UserRoleRel rel) {
|
||||
String sql = "insert into " + DBContext.userRoleRel + " (userId,roleId) values" + "(" + rel.getUserId() + ","
|
||||
+ rel.getRoleId() + ")";
|
||||
int state = 0;
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
public int deleteUserRoleRel(Statement statement, UserRoleRel rel) {
|
||||
String sql = "delete from " + DBContext.userRoleRel + " where userId=" + rel.getUserId() + " and roleId="
|
||||
+ rel.getRoleId();
|
||||
int state = 0;
|
||||
|
||||
try {
|
||||
state = statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* The exception for authority model
|
||||
* Created by liukun on 17/1/4.
|
||||
*/
|
||||
public class AuthException extends Exception {
|
||||
public AuthException(String format, String userName, String roleName) {
|
||||
super();
|
||||
}
|
||||
|
||||
public AuthException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AuthException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AuthException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
protected AuthException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* The
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class DBContext {
|
||||
|
||||
public static final String userTable = "userTable";
|
||||
public static final String roleTable = "roleTable";
|
||||
public static final String userRoleRel = "userRoleRelTable";
|
||||
public static final String userPermission = "userPermissionTable";
|
||||
public static final String rolePermission = "rolePermissionTable";
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class Permission {
|
||||
|
||||
public static final int CREATE = 0;
|
||||
public static final int INSERT = 1;
|
||||
public static final int MODIFY = 2;
|
||||
public static final int READ = 3;
|
||||
public static final int DELETE = 4;
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class Role {
|
||||
|
||||
private int id;
|
||||
private String roleName;
|
||||
/**
|
||||
* @param id
|
||||
* @param roleName
|
||||
*/
|
||||
public Role(int id, String roleName) {
|
||||
this.id = id;
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public Role(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public Role(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roleName
|
||||
*/
|
||||
public String getRoleName() {
|
||||
return roleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roleName the roleName to set
|
||||
*/
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class RolePermission {
|
||||
|
||||
private int id;
|
||||
private int roleId;
|
||||
private String nodeName;
|
||||
private int permissionId;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param roleId
|
||||
* @param permissionId
|
||||
*/
|
||||
public RolePermission(int id, int roleId, String nodeName, int permissionId) {
|
||||
this.id = id;
|
||||
this.roleId = roleId;
|
||||
this.nodeName = nodeName;
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
public RolePermission(int roleId, String nodeName, int permissionId) {
|
||||
this.roleId = roleId;
|
||||
this.nodeName = nodeName;
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
public RolePermission() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the id to set
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodeName
|
||||
*/
|
||||
public String getNodeName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeName
|
||||
* the nodeName to set
|
||||
*/
|
||||
public void setNodeName(String nodeName) {
|
||||
this.nodeName = nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the roleId
|
||||
*/
|
||||
public int getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roleId
|
||||
* the roleId to set
|
||||
*/
|
||||
public void setRoleId(int roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the permissionId
|
||||
*/
|
||||
public int getPermissionId() {
|
||||
return permissionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permissionId
|
||||
* the permissionId to set
|
||||
*/
|
||||
public void setPermissionId(int permissionId) {
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class User {
|
||||
|
||||
private int id;
|
||||
private String userName;
|
||||
private String passWord;
|
||||
private boolean locked;//true - t false - f
|
||||
private String validTime;
|
||||
/**
|
||||
* @param id
|
||||
* @param userName
|
||||
* @param passWord
|
||||
* @param isLock
|
||||
* @param validTime
|
||||
*/
|
||||
public User(int id, String userName, String passWord, boolean isLock, String validTime) {
|
||||
this.id = id;
|
||||
this.userName = userName;
|
||||
this.passWord = passWord;
|
||||
this.locked = isLock;
|
||||
this.validTime = validTime;
|
||||
}
|
||||
|
||||
public User(){
|
||||
|
||||
}
|
||||
|
||||
public User(String userName, String passWord) {
|
||||
this.userName = userName;
|
||||
this.passWord = passWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userName
|
||||
*/
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userName the userName to set
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the passWord
|
||||
*/
|
||||
public String getPassWord() {
|
||||
return passWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param passWord the passWord to set
|
||||
*/
|
||||
public void setPassWord(String passWord) {
|
||||
this.passWord = passWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isLock
|
||||
*/
|
||||
public boolean isLock() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isLock the isLock to set
|
||||
*/
|
||||
public void setLock(boolean isLock) {
|
||||
this.locked = isLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validTime
|
||||
*/
|
||||
public String getValidTime() {
|
||||
return validTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param validTime the validTime to set
|
||||
*/
|
||||
public void setValidTime(String validTime) {
|
||||
this.validTime = validTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class UserPermission {
|
||||
|
||||
private int id;
|
||||
private int userId;
|
||||
private String nodeName;
|
||||
private int permissionId;// 权限的值必须是permission中的,在数据库中使用check方法来指定
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param userId
|
||||
* @param nodeName
|
||||
* @param permissionId
|
||||
*/
|
||||
public UserPermission(int id, int userId, String nodeName, int permissionId) {
|
||||
this.id = id;
|
||||
this.userId = userId;
|
||||
this.nodeName = nodeName;
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
public UserPermission() {
|
||||
|
||||
}
|
||||
|
||||
public UserPermission(int userId, String nodeName, int permissionId) {
|
||||
this.userId = userId;
|
||||
this.nodeName = nodeName;
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the id to set
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userId
|
||||
*/
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userId
|
||||
* the userId to set
|
||||
*/
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nodeName
|
||||
*/
|
||||
public String getNodeName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeName
|
||||
* the nodeName to set
|
||||
*/
|
||||
public void setNodeName(String nodeName) {
|
||||
this.nodeName = nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the permissionId
|
||||
*/
|
||||
public int getPermissionId() {
|
||||
return permissionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permissionId
|
||||
* the permissionId to set
|
||||
*/
|
||||
public void setPermissionId(int permissionId) {
|
||||
this.permissionId = permissionId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package cn.edu.thu.tsfiledb.auth.model;
|
||||
|
||||
/**
|
||||
* @author liukun
|
||||
*
|
||||
*/
|
||||
public class UserRoleRel {
|
||||
private int id;
|
||||
private int userId;
|
||||
private int roleId;
|
||||
/**
|
||||
* @param id
|
||||
* @param userId
|
||||
* @param roleId
|
||||
*/
|
||||
public UserRoleRel(int id, int userId, int roleId) {
|
||||
this.id = id;
|
||||
this.userId = userId;
|
||||
this.roleId = roleId;
|
||||
}
|
||||
public UserRoleRel(int userId,int roleId){
|
||||
this.userId = userId;
|
||||
this.roleId = roleId;
|
||||
}
|
||||
public UserRoleRel() {
|
||||
|
||||
}
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* @return the userId
|
||||
*/
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
/**
|
||||
* @param userId the userId to set
|
||||
*/
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
/**
|
||||
* @return the roleId
|
||||
*/
|
||||
public int getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
/**
|
||||
* @param roleId the roleId to set
|
||||
*/
|
||||
public void setRoleId(int roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package cn.edu.thu.tsfiledb.engine.exception;
|
||||
|
||||
public class LRUManagerException extends Exception {
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
|
||||
public class LRUManagerException extends ProcessorException {
|
||||
|
||||
private static final long serialVersionUID = 3426203851432238314L;
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import cn.edu.thu.tsfiledb.engine.overflow.io.OverflowProcessor;
|
|||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.ColumnSchema;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
import cn.edu.thu.tsfiledb.query.engine.OverflowQueryEngine;
|
||||
|
||||
public class FileNodeProcessor extends LRUProcessor {
|
||||
|
||||
|
@ -791,7 +792,12 @@ public class FileNodeProcessor extends LRUProcessor {
|
|||
long endTime = -1;
|
||||
|
||||
OverflowQueryEngine queryEngine = new OverflowQueryEngine();
|
||||
data = queryEngine.query(pathList, timeFilter, null, null, null, TsFileConf.defaultFetchSize);
|
||||
try {
|
||||
data = queryEngine.query(pathList, timeFilter, null, null, null, TsFileConf.defaultFetchSize);
|
||||
} catch (ProcessorException e1) {
|
||||
e1.printStackTrace();
|
||||
throw new IOException("Exception when merge");
|
||||
}
|
||||
if (!data.hasNextRecord()) {
|
||||
// No record in this query
|
||||
LOGGER.info("Merge query: namespace {}, time filter {}, no query data", nameSpacePath, timeFilter);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package cn.edu.thu.tsfiledb.engine.filenode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
|
||||
public class OverflowQueryEngine {
|
||||
|
||||
public QueryDataSet query(List<Path> pathList, FilterExpression timeFilter, Object object, Object object2,
|
||||
Object object3, int defaultFetchSize) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
package cn.edu.thu.tsfiledb.qp.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* this class contains several constants used in SQL.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class SQLConstant {
|
||||
public static final String MREGE_EXTENSION = "merge";
|
||||
public static final String ERR_EXTENSION = "err";
|
||||
public static final String PATH_SEPARATOR = ".";
|
||||
public static final String PATH_SEPARATER_NO_REGEX = "\\.";
|
||||
|
||||
public static final String DEFAULT_DELTA_OBJECT_TYPE = "defalut_delta_object_type";
|
||||
|
||||
public static final String RESERVED_TIME = "time";
|
||||
public static final String RESERVED_FREQ = "freq";
|
||||
public static final String RESERVED_DELTA_OBJECT = "delta_object";
|
||||
public static final String IS_AGGREGATION = "IS_AGGREGATION";
|
||||
|
||||
public static final String lineFeedSignal = "\n";
|
||||
public static final String ROOT = "root";
|
||||
public static final String METADATA_PARAM_EQUAL = "=";
|
||||
|
||||
public static final int KW_AND = 1;
|
||||
public static final int KW_OR = 2;
|
||||
public static final int KW_NOT = 3;
|
||||
|
||||
public static final int EQUAL = 11;
|
||||
public static final int NOTEQUAL = 12;
|
||||
public static final int LESSTHANOREQUALTO = 13;
|
||||
public static final int LESSTHAN = 14;
|
||||
public static final int GREATERTHANOREQUALTO = 15;
|
||||
public static final int GREATERTHAN = 16;
|
||||
public static final int EQUAL_NS = 17;
|
||||
|
||||
public static final int TOK_SELECT = 21;
|
||||
public static final int TOK_FROM = 22;
|
||||
public static final int TOK_WHERE = 23;
|
||||
public static final int TOK_INSERT = 24;
|
||||
public static final int TOK_DELETE = 25;
|
||||
public static final int TOK_UPDATE = 26;
|
||||
public static final int TOK_QUERY = 27;
|
||||
public static final int TOK_MULTIINSERT = 28;
|
||||
// public static final int TOK_VIRTUAL_TABLE = 30;
|
||||
// public static final int TOK_TABNAME = 31;
|
||||
// public static final int TOK_TABREF = 32;
|
||||
|
||||
public static final int TOK_AUTHOR_CREATE = 41;
|
||||
public static final int TOK_AUTHOR_DROP = 42;
|
||||
public static final int TOK_AUTHOR_GRANT = 43;
|
||||
public static final int TOK_AUTHOR_REVOKE = 44;
|
||||
/**
|
||||
* 这是是刘昆修改的,为了update user的密码
|
||||
*/
|
||||
public static final int TOK_AUTHOR_UPDATE_USER = 46;
|
||||
|
||||
public static final int TOK_DATALOAD = 45;
|
||||
|
||||
public static final int TOK_METADATA_CREATE = 51;
|
||||
public static final int TOK_METADATA_DELETE = 52;
|
||||
public static final int TOK_METADATA_SET_FILE_LEVEL = 53;
|
||||
public static final int TOK_PORPERTY_CREATE = 54;
|
||||
public static final int TOK_PORPERTY_ADD_LABEL = 55;
|
||||
public static final int TOK_PORPERTY_DELETE_LABEL = 56;
|
||||
public static final int TOK_PORPERTY_LINK = 57;
|
||||
public static final int TOK_PORPERTY_UNLINK = 58;
|
||||
|
||||
|
||||
|
||||
public static Map<Integer, String> tokenSymbol = new HashMap<Integer, String>();
|
||||
public static Map<Integer, String> tokenNames = new HashMap<Integer, String>();
|
||||
public static Map<Integer, Integer> reverseWords = new HashMap<Integer, Integer>();
|
||||
|
||||
static {
|
||||
tokenSymbol.put(KW_AND, "&");
|
||||
tokenSymbol.put(KW_OR, "|");
|
||||
tokenSymbol.put(KW_NOT, "!");
|
||||
tokenSymbol.put(EQUAL, "=");
|
||||
tokenSymbol.put(NOTEQUAL, "<>");
|
||||
tokenSymbol.put(EQUAL_NS, "<=>");
|
||||
tokenSymbol.put(LESSTHANOREQUALTO, "<=");
|
||||
tokenSymbol.put(LESSTHAN, "<");
|
||||
tokenSymbol.put(GREATERTHANOREQUALTO, ">=");
|
||||
tokenSymbol.put(GREATERTHAN, ">");
|
||||
}
|
||||
|
||||
static {
|
||||
tokenNames.put(KW_AND, "and");
|
||||
tokenNames.put(KW_OR, "or");
|
||||
tokenNames.put(KW_NOT, "not");
|
||||
tokenNames.put(EQUAL, "equal");
|
||||
tokenNames.put(NOTEQUAL, "not_equal");
|
||||
tokenNames.put(EQUAL_NS, "equal_ns");
|
||||
tokenNames.put(LESSTHANOREQUALTO, "lessthan_or_equalto");
|
||||
tokenNames.put(LESSTHAN, "lessthan");
|
||||
tokenNames.put(GREATERTHANOREQUALTO, "greaterthan_or_equalto");
|
||||
tokenNames.put(GREATERTHAN, "greaterthan");
|
||||
|
||||
tokenNames.put(TOK_SELECT, "TOK_SELECT");
|
||||
tokenNames.put(TOK_FROM, "TOK_FROM");
|
||||
tokenNames.put(TOK_WHERE, "TOK_WHERE");
|
||||
tokenNames.put(TOK_INSERT, "TOK_INSERT");
|
||||
tokenNames.put(TOK_DELETE, "TOK_DELETE");
|
||||
tokenNames.put(TOK_UPDATE, "TOK_UPDATE");
|
||||
tokenNames.put(TOK_QUERY, "TOK_QUERY");
|
||||
tokenNames.put(TOK_MULTIINSERT, "TOK_MULTIINSERT");
|
||||
|
||||
tokenNames.put(TOK_AUTHOR_CREATE, "TOK_AUTHOR_CREATE");
|
||||
tokenNames.put(TOK_AUTHOR_DROP, "TOK_AUTHOR_DROP");
|
||||
tokenNames.put(TOK_AUTHOR_GRANT, "TOK_AUTHOR_GRANT");
|
||||
tokenNames.put(TOK_AUTHOR_REVOKE, "TOK_AUTHOR_REVOKE");
|
||||
/**
|
||||
* 这是是刘昆修改的,为了update user的密码
|
||||
*/
|
||||
tokenNames.put(TOK_AUTHOR_UPDATE_USER, "TOK_AUTHOR_UPDATE_USER");
|
||||
tokenNames.put(TOK_DATALOAD, "TOK_DATALOAD");
|
||||
|
||||
tokenNames.put(TOK_METADATA_CREATE, "TOK_METADATA_CREATE");
|
||||
tokenNames.put(TOK_METADATA_DELETE, "TOK_METADATA_DELETE");
|
||||
tokenNames.put(TOK_METADATA_SET_FILE_LEVEL, "TOK_METADATA_SET_FILE_LEVEL");
|
||||
tokenNames.put(TOK_PORPERTY_CREATE, "TOK_PORPERTY_CREATE");
|
||||
tokenNames.put(TOK_PORPERTY_ADD_LABEL, "TOK_PORPERTY_ADD_LABEL");
|
||||
tokenNames.put(TOK_PORPERTY_DELETE_LABEL, "TOK_PORPERTY_DELETE_LABEL");
|
||||
tokenNames.put(TOK_PORPERTY_LINK, "TOK_PORPERTY_LINK");
|
||||
tokenNames.put(TOK_PORPERTY_UNLINK, "TOK_PORPERTY_UNLINK");
|
||||
|
||||
}
|
||||
|
||||
static {
|
||||
reverseWords.put(KW_AND, KW_OR);
|
||||
reverseWords.put(KW_OR, KW_AND);
|
||||
reverseWords.put(EQUAL, NOTEQUAL);
|
||||
reverseWords.put(NOTEQUAL, EQUAL);
|
||||
reverseWords.put(LESSTHAN, GREATERTHANOREQUALTO);
|
||||
reverseWords.put(GREATERTHANOREQUALTO, LESSTHAN);
|
||||
reverseWords.put(LESSTHANOREQUALTO, GREATERTHAN);
|
||||
reverseWords.put(GREATERTHAN, LESSTHANOREQUALTO);
|
||||
}
|
||||
|
||||
public static boolean isReservedPath(Path pathStr) {
|
||||
return pathStr.equals(SQLConstant.RESERVED_TIME)
|
||||
|| pathStr.equals(SQLConstant.RESERVED_FREQ)
|
||||
|| pathStr.equals(SQLConstant.RESERVED_DELTA_OBJECT);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception;
|
||||
|
||||
/**
|
||||
* This exception is for calling error method in {@linkplain com.corp.tsfile.sql.exec.TSqlParserV2
|
||||
* TSqlParserV2}.<br>
|
||||
* Throw this exception if user call {@code nonQuery} method from a {@code QUERY operator}, or call
|
||||
* {@code getIndex getIndex} method from a {@code NonQUERY operator}, like AUTHOR, LOADDATA,
|
||||
* UPDATE,INSERT, DELETE
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class ErrorQueryOpException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = -262405196554416563L;
|
||||
|
||||
public ErrorQueryOpException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception;
|
||||
|
||||
public class IllegalASTFormatException extends QueryProcessorException {
|
||||
private static final long serialVersionUID = -8987915911329315588L;
|
||||
|
||||
public IllegalASTFormatException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception;
|
||||
|
||||
public class QueryProcessorException extends Exception {
|
||||
private static final long serialVersionUID = -8987915921329335088L;
|
||||
|
||||
protected String errMsg;
|
||||
public QueryProcessorException(String msg) {
|
||||
super(msg);
|
||||
this.errMsg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception;
|
||||
|
||||
/**
|
||||
* This exception is threw while meeting error in transforming a logical operator to a physical
|
||||
* plan.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class TSTransformException extends QueryProcessorException {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7573857366601268706L;
|
||||
|
||||
public TSTransformException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.BasicFunctionOperator BasicFunctionOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class BasicOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = -2163809754074237707L;
|
||||
|
||||
public BasicOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.DeleteOperator DeleteOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class DeleteOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = 5532624124231495807L;
|
||||
|
||||
public DeleteOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator FilterOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class FilterOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = 167597682291449523L;
|
||||
|
||||
public FilterOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.InsertOperator InsertOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class InsertOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = -6280121806646850135L;
|
||||
|
||||
public InsertOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
public class ParseLeafException extends QpWhereException {
|
||||
private static final long serialVersionUID = -8987115911329315088L;
|
||||
|
||||
public ParseLeafException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
public class ParseTimeException extends QpWhereException {
|
||||
private static final long serialVersionUID = -5838261873402031565L;
|
||||
|
||||
public ParseTimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class QpSelectFromException extends QueryProcessorException {
|
||||
private static final long serialVersionUID = -8987543591129315588L;
|
||||
|
||||
public QpSelectFromException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class QpWhereException extends QueryProcessorException {
|
||||
private static final long serialVersionUID = -8987915911329315088L;
|
||||
|
||||
public QpWhereException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.QueryOperator QueryOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class QueryOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = 4466703029858082216L;
|
||||
|
||||
public QueryOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
public class SeriesNotExistException extends QpSelectFromException {
|
||||
private static final long serialVersionUID = -5838261873402011565L;
|
||||
|
||||
public SeriesNotExistException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class SetClauseException extends QueryProcessorException {
|
||||
private static final long serialVersionUID = -8987915921329315088L;
|
||||
|
||||
public SetClauseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
/**
|
||||
* This exception is threw whiling meeting error in
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.operator.crud.UpdateOperator UpdateOperator}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class UpdateOperatorException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = -797390809639488007L;
|
||||
|
||||
public UpdateOperatorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class ValueParseException extends QueryProcessorException {
|
||||
private static final long serialVersionUID = -8987281211329315088L;
|
||||
|
||||
public ValueParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.optimize;
|
||||
|
||||
|
||||
public class DNFOptimizeException extends LogicalOptimizeException {
|
||||
|
||||
private static final long serialVersionUID = 807384397361662482L;
|
||||
|
||||
public DNFOptimizeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.optimize;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class LogicalOptimizeException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = -7098092782689670064L;
|
||||
|
||||
public LogicalOptimizeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.optimize;
|
||||
|
||||
|
||||
public class MergeFilterException extends LogicalOptimizeException {
|
||||
|
||||
private static final long serialVersionUID = 8581594261924961899L;
|
||||
|
||||
public MergeFilterException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.optimize;
|
||||
|
||||
|
||||
public class PathConcatException extends LogicalOptimizeException {
|
||||
|
||||
private static final long serialVersionUID = 1789858025764650098L;
|
||||
|
||||
public PathConcatException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.logical.optimize;
|
||||
|
||||
|
||||
public class RemoveNotException extends LogicalOptimizeException {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -772591029262375715L;
|
||||
|
||||
public RemoveNotException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.physical.plan;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
|
||||
public class NamespacePlanException extends PhysicalPlanException {
|
||||
|
||||
private static final long serialVersionUID = -2069701664732857589L;
|
||||
|
||||
public NamespacePlanException(String msg){
|
||||
super(msg);
|
||||
}
|
||||
public NamespacePlanException(String msg, Exception exception) {
|
||||
super(msg);
|
||||
StringContainer sc = new StringContainer(",");
|
||||
sc.addTail("error message:", msg, "meet other exceptions:");
|
||||
sc.addTail("exception type", exception.getClass().toString(), "exception message",
|
||||
exception.getMessage());
|
||||
errMsg = sc.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exception.physical.plan;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
|
||||
public class PhysicalPlanException extends QueryProcessorException {
|
||||
|
||||
private static final long serialVersionUID = 2730849997674197054L;
|
||||
|
||||
public PhysicalPlanException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exec;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterFactory;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.SingleSeriesFilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.filterseries.FilterSeries;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.BasicOperatorException;
|
||||
|
||||
/**
|
||||
* all basic operator in filter
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public enum BasicOperatorType {
|
||||
EQ {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.eq(column, value);
|
||||
}
|
||||
},
|
||||
LTEQ {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.ltEq(column, value, true);
|
||||
}
|
||||
},
|
||||
LT {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.ltEq(column, value, false);
|
||||
}
|
||||
},
|
||||
GTEQ {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.gtEq(column, value, true);
|
||||
}
|
||||
},
|
||||
GT {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.gtEq(column, value, false);
|
||||
}
|
||||
},
|
||||
NOTEQUAL {
|
||||
@Override
|
||||
public <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value) {
|
||||
return FilterFactory.noteq(column, value);
|
||||
}
|
||||
};
|
||||
private static Logger LOG = LoggerFactory.getLogger(BasicOperatorType.class);
|
||||
|
||||
public static BasicOperatorType getBasicOpBySymbol(int tokenIntType)
|
||||
throws BasicOperatorException {
|
||||
switch (tokenIntType) {
|
||||
case SQLConstant.EQUAL:
|
||||
return EQ;
|
||||
case SQLConstant.LESSTHANOREQUALTO:
|
||||
return LTEQ;
|
||||
case SQLConstant.LESSTHAN:
|
||||
return LT;
|
||||
case SQLConstant.GREATERTHANOREQUALTO:
|
||||
return GTEQ;
|
||||
case SQLConstant.GREATERTHAN:
|
||||
return GT;
|
||||
case SQLConstant.NOTEQUAL:
|
||||
return NOTEQUAL;
|
||||
default:
|
||||
throw new BasicOperatorException("unsupported type:{}"
|
||||
+ SQLConstant.tokenNames.get(tokenIntType));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract <T extends Comparable<T>, C extends FilterSeries<T>> SingleSeriesFilterExpression getSingleSeriesFilterExpression(
|
||||
C column, T value);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exec;
|
||||
|
||||
/**
|
||||
* condition has three type:time, freq(frequency) and ordinary value.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public enum FilterType {
|
||||
TIME(0), FREQ(1), VALUE(2);
|
||||
private int typeCode;
|
||||
|
||||
private FilterType(int i) {
|
||||
typeCode = i;
|
||||
}
|
||||
|
||||
public int getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
public static FilterType valueOfStr(String v) {
|
||||
v = v.toLowerCase();
|
||||
switch (v) {
|
||||
case "time":
|
||||
return TIME;
|
||||
case "freq":
|
||||
return FREQ;
|
||||
default:
|
||||
return VALUE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exec;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.derby.iapi.error.PublicAPI;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.file.metadata.enums.TSDataType;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfiledb.auth.dao.Authorizer;
|
||||
import cn.edu.thu.tsfiledb.auth.model.AuthException;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
|
||||
public abstract class QueryProcessExecutor {
|
||||
protected final boolean isSingleFile;
|
||||
/**
|
||||
* parameters allows to set and get user-defined parameters.
|
||||
*/
|
||||
protected ThreadLocal<Map<String, Object>> parameters = new ThreadLocal<Map<String, Object>>();
|
||||
protected int fetchSize = 100;
|
||||
|
||||
public QueryProcessExecutor(boolean isSingleFile) {
|
||||
this.isSingleFile = isSingleFile;
|
||||
}
|
||||
|
||||
protected abstract TSDataType getNonReseveredSeriesType(Path fullPath);
|
||||
|
||||
protected abstract boolean judgeNonReservedPathExists(Path fullPath);
|
||||
|
||||
public boolean isSingleFile() {
|
||||
return isSingleFile;
|
||||
}
|
||||
|
||||
public TSDataType getSeriesType(Path fullPath) {
|
||||
if (fullPath.equals(SQLConstant.RESERVED_TIME))
|
||||
return TSDataType.INT64;
|
||||
if (fullPath.equals(SQLConstant.RESERVED_FREQ))
|
||||
return TSDataType.FLOAT;
|
||||
if (fullPath.equals(SQLConstant.RESERVED_DELTA_OBJECT))
|
||||
return TSDataType.BYTE_ARRAY;
|
||||
return getNonReseveredSeriesType(fullPath);
|
||||
}
|
||||
|
||||
public boolean judgePathExists(Path pathStr) {
|
||||
if (SQLConstant.isReservedPath(pathStr))
|
||||
return true;
|
||||
else
|
||||
return judgeNonReservedPathExists(pathStr);
|
||||
}
|
||||
|
||||
public void setFetchSize(int fetchSize) {
|
||||
this.fetchSize = fetchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* in getIndex command, fetchSize must be specified at first.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getFetchSize() {
|
||||
return fetchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param paths
|
||||
* @param timeFilter
|
||||
* @param freqFilter
|
||||
* @param valueFilter
|
||||
* @param fetchSize
|
||||
* @param lastData
|
||||
* @return
|
||||
*/
|
||||
public abstract QueryDataSet query(List<Path> paths, FilterExpression timeFilter,
|
||||
FilterExpression freqFilter, FilterExpression valueFilter, int fetchSize,
|
||||
QueryDataSet lastData) throws ProcessorException;
|
||||
|
||||
/**
|
||||
* execute update command and return whether the operator is successful.
|
||||
*
|
||||
* @param path : update series path
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
* @param value - in type of string
|
||||
* @return - whether the operator is successful.
|
||||
*/
|
||||
public abstract boolean update(Path path, long startTime, long endTime, String value) throws ProcessorException;
|
||||
|
||||
/**
|
||||
* execute delete command and return whether the operator is successful.
|
||||
*
|
||||
* @param path : delete series path
|
||||
* @param deleteTime
|
||||
* @return - whether the operator is successful.
|
||||
*/
|
||||
public abstract boolean delete(Path path, long deleteTime) throws ProcessorException;
|
||||
|
||||
/**
|
||||
* execute insert command and return whether the operator is successful.
|
||||
*
|
||||
* @param path
|
||||
* @param insertTime - it's time point but not a range
|
||||
* @param value
|
||||
* @return - Operate Type.
|
||||
*/
|
||||
public abstract int insert(Path path, long insertTime, String value) throws ProcessorException;
|
||||
|
||||
public abstract int multiInsert(String deltaObject, long insertTime,
|
||||
List<String> measurementList, List<String> insertValues) throws ProcessorException;
|
||||
|
||||
public MManager getMManager() {
|
||||
return MManager.getInstance();
|
||||
}
|
||||
|
||||
public void addParameter(String key, Object value) {
|
||||
if(parameters.get() == null){
|
||||
parameters.set(new HashMap<String, Object>());
|
||||
}
|
||||
parameters.get().put(key, value);
|
||||
}
|
||||
|
||||
public Object getParameter(String key) {
|
||||
return parameters.get().get(key);
|
||||
}
|
||||
|
||||
public void clearParamter(){
|
||||
if(parameters.get() != null){
|
||||
parameters.get().clear();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 刘昆修改,添加修改用户密码功能
|
||||
*/
|
||||
public boolean updateUser(String username,String newPassword) throws AuthException{
|
||||
return Authorizer.updateUserPassword(username, newPassword);
|
||||
}
|
||||
|
||||
public boolean createUser(String username, String password) throws AuthException {
|
||||
return Authorizer.createUser(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在,权限编号不对等
|
||||
*/
|
||||
public boolean addPmsToUser(String userName, String nodeName, int permissionId)
|
||||
throws AuthException {
|
||||
return Authorizer.addPmsToUser(userName, nodeName, permissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在;用户不具有该权限
|
||||
*/
|
||||
public boolean removePmsFromUser(String userName, String nodeName, int permissionId)
|
||||
throws AuthException {
|
||||
return Authorizer.removePmsFromUser(userName, nodeName, permissionId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在
|
||||
*/
|
||||
public boolean deleteUser(String userName) throws AuthException {
|
||||
return Authorizer.deleteUser(userName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 异常可能:角色已经存在
|
||||
*/
|
||||
public boolean createRole(String roleName) throws AuthException {
|
||||
return Authorizer.createRole(roleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:角色不存在,或者权限ID不对
|
||||
*/
|
||||
public boolean addPmsToRole(String roleName, String nodeName, int permissionId)
|
||||
throws AuthException {
|
||||
return Authorizer.addPmsToRole(roleName, nodeName, permissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:角色不存在;权限ID不对;角色本来不拥有该权限
|
||||
*/
|
||||
public boolean removePmsFromRole(String roleName, String nodeName, int permissionId)
|
||||
throws AuthException {
|
||||
return Authorizer.removePmsFromRole(roleName, nodeName, permissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:角色不存在
|
||||
*/
|
||||
public boolean deleteRole(String roleName) throws AuthException {
|
||||
return Authorizer.deleteRole(roleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在;角色不存在;该用户已经拥有该该角色
|
||||
*/
|
||||
public boolean grantRoleToUser(String roleName, String username) throws AuthException {
|
||||
return Authorizer.grantRoleToUser(roleName, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在;角色不存在;该用户没有该角色
|
||||
*/
|
||||
public boolean revokeRoleFromUser(String roleName, String username) throws AuthException {
|
||||
return Authorizer.revokeRoleFromUser(roleName, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常可能:用户不存在
|
||||
*/
|
||||
public Set<Integer> getPermissions(String username, String nodeName) throws AuthException {
|
||||
return Authorizer.getPermission(username, nodeName);
|
||||
}
|
||||
|
||||
public PhysicalPlan queryPhysicalOptimize(PhysicalPlan plan) {
|
||||
return plan;
|
||||
}
|
||||
|
||||
public PhysicalPlan nonQueryPhysicalOptimize(PhysicalPlan plan) {
|
||||
return plan;
|
||||
}
|
||||
|
||||
public List<String> getAllPaths(String fullPath) throws PathErrorException {
|
||||
return getMManager().getPaths(fullPath);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package cn.edu.thu.tsfiledb.qp.exec.impl;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.file.metadata.enums.TSDataType;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfile.timeseries.write.record.DataPoint;
|
||||
import cn.edu.thu.tsfile.timeseries.write.record.TSRecord;
|
||||
import cn.edu.thu.tsfiledb.engine.filenode.FileNodeManager;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.query.engine.OverflowQueryEngine;
|
||||
|
||||
public class OverflowQPExecutor extends QueryProcessExecutor {
|
||||
|
||||
static final Logger logger = LoggerFactory.getLogger(OverflowQPExecutor.class);
|
||||
private OverflowQueryEngine queryEngine;
|
||||
private FileNodeManager fileNodeManager;
|
||||
|
||||
public OverflowQPExecutor() {
|
||||
super(false);
|
||||
queryEngine = new OverflowQueryEngine();
|
||||
fileNodeManager = FileNodeManager.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TSDataType getNonReseveredSeriesType(Path path) {
|
||||
try {
|
||||
return MManager.getInstance().getSeriesType(path.getFullPath());
|
||||
} catch (PathErrorException e) {
|
||||
logger.error("path error in getSeriesType. Path: " + path.getFullPath() + "ErrorMsg: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean judgeNonReservedPathExists(Path path) {
|
||||
return MManager.getInstance().pathExist(path.getFullPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryDataSet query(List<Path> paths, FilterExpression timeFilter, FilterExpression freqFilter,
|
||||
FilterExpression valueFilter, int fetchSize, QueryDataSet lastData) throws ProcessorException {
|
||||
QueryDataSet ret;
|
||||
try {
|
||||
if (parameters.get() != null && parameters.get().containsKey(SQLConstant.IS_AGGREGATION)) {
|
||||
if (lastData != null) {
|
||||
lastData.clear();
|
||||
return lastData;
|
||||
}
|
||||
String aggrFuncName = (String) parameters.get().get(SQLConstant.IS_AGGREGATION);
|
||||
ret = queryEngine.aggregate(paths.get(0), aggrFuncName, timeFilter, freqFilter, valueFilter);
|
||||
} else {
|
||||
ret = queryEngine.query(paths, timeFilter, freqFilter, valueFilter, lastData, fetchSize);
|
||||
}
|
||||
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
logger.error("Error in query", e);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(Path path, long startTime, long endTime, String value) throws ProcessorException {
|
||||
String device = path.getDeltaObjectToString();
|
||||
String sensor = path.getMeasurementToString();
|
||||
|
||||
try {
|
||||
TSDataType type = queryEngine.getDataTypeByDeviceAndSensor(device, sensor);
|
||||
fileNodeManager.update(device, sensor, startTime, endTime, type, value);
|
||||
return true;
|
||||
} catch (PathErrorException e) {
|
||||
throw new ProcessorException("Error in update: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(Path path, long timestamp) throws ProcessorException {
|
||||
// TODO Auto-generated method stub
|
||||
String device = path.getDeltaObjectToString();
|
||||
String sensor = path.getMeasurementToString();
|
||||
try {
|
||||
TSDataType type = queryEngine.getDataTypeByDeviceAndSensor(device, sensor);
|
||||
fileNodeManager.delete(device, sensor, timestamp, type);
|
||||
return true;
|
||||
} catch (PathErrorException e) {
|
||||
throw new ProcessorException("Error in delete: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// return 0: failed, 1: Overflow, 2:Bufferwrite
|
||||
public int insert(Path path, long timestamp, String value) throws ProcessorException {
|
||||
String device = path.getDeltaObjectToString();
|
||||
String sensor = path.getMeasurementToString();
|
||||
|
||||
try {
|
||||
TSDataType type = queryEngine.getDataTypeByDeviceAndSensor(device, sensor);
|
||||
TSRecord tsRecord = new TSRecord(timestamp, device);
|
||||
DataPoint dataPoint = DataPoint.getDataPoint(type, sensor, value);
|
||||
tsRecord.addTuple(dataPoint);
|
||||
return fileNodeManager.insert(tsRecord);
|
||||
|
||||
} catch (PathErrorException e) {
|
||||
throw new ProcessorException("Error in insert: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int multiInsert(String deltaObject, long insertTime, List<String> measurementList, List<String> insertValues)
|
||||
throws ProcessorException {
|
||||
try {
|
||||
MManager mManager = MManager.getInstance();
|
||||
TSRecord tsRecord = new TSRecord(insertTime, deltaObject);
|
||||
|
||||
for (int i = 0 ; i < measurementList.size() ; i ++) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(deltaObject);
|
||||
sb.append(".");
|
||||
sb.append(measurementList.get(i));
|
||||
String p = sb.toString();
|
||||
if(!mManager.pathExist(p)){
|
||||
throw new ProcessorException("Path not exists:" + p);
|
||||
}
|
||||
TSDataType dataType = mManager.getSeriesType(p);
|
||||
DataPoint dataPoint = DataPoint.getDataPoint(dataType, measurementList.get(i), insertValues.get(i));
|
||||
tsRecord.addTuple(dataPoint);
|
||||
}
|
||||
return fileNodeManager.insert(tsRecord);
|
||||
|
||||
} catch (PathErrorException e) {
|
||||
throw new ProcessorException("Path error:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
|
||||
/**
|
||||
* This class is a superclass of all operator.
|
||||
*
|
||||
* @author kangrong
|
||||
*/
|
||||
public abstract class Operator {
|
||||
protected int tokenIntType;
|
||||
protected String tokenName;
|
||||
|
||||
protected OperatorType operatorType = OperatorType.NULL;
|
||||
|
||||
public Operator(int tokenIntType) {
|
||||
this.tokenIntType = tokenIntType;
|
||||
this.tokenName = SQLConstant.tokenNames.get(tokenIntType);
|
||||
}
|
||||
|
||||
public OperatorType getType() {
|
||||
return operatorType;
|
||||
}
|
||||
|
||||
public boolean isQuery() {
|
||||
return operatorType == OperatorType.QUERY;
|
||||
}
|
||||
|
||||
public int getTokenIntType() {
|
||||
return tokenIntType;
|
||||
}
|
||||
|
||||
public String getTokenName() {
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
public enum OperatorType {
|
||||
ROOT, JOIN, UNION, FILTER, GROUPBY, ORDERBY, LIMIT, SELECT, SEQTABLESCAN, HASHTABLESCAN, MERGEJOIN, FILEREAD, NULL, TABLESCAN,
|
||||
UPDATE, MULTIINSERT, INSERT, DELETE, BASIC_FUNC, QUERY, AUTHOR, FROM, FUNC, LOADDATA, METADATA, PROPERTY
|
||||
, OVERFLOWFLUSHSTART, // 25
|
||||
// ordinal()
|
||||
OVERFLOWFLUSHEND, // 26
|
||||
BUFFERFLUSHSTART, // 27
|
||||
BUFFERFLUSHEND; // 28
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* RootOperator indicates the operator that could be executed as a entire command. RootOperator
|
||||
* consists of SFWOperator, like INSERT/UPDATE/DELETE, and AuthorOperator.
|
||||
*
|
||||
* @author kangrong
|
||||
*/
|
||||
public abstract class RootOperator extends Operator {
|
||||
|
||||
|
||||
public RootOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
}
|
||||
|
||||
/**
|
||||
* transform this root operator tree to a physical plan tree.Node that, before this method
|
||||
* called, the where filter has been dealt with
|
||||
* {@linkplain cn.edu.thu.tsfiledb.qp.logical.optimizer.filter.MergeSingleFilterOptimizer}
|
||||
*/
|
||||
public abstract PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException;
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.author;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.AuthorPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* this class maintains information in Author statement, including CREATE, DROP, GRANT and REVOKE
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class AuthorOperator extends RootOperator {
|
||||
|
||||
public AuthorOperator(int tokenIntType, AuthorType type) {
|
||||
super(tokenIntType);
|
||||
authorType = type;
|
||||
operatorType = OperatorType.AUTHOR;
|
||||
}
|
||||
|
||||
private final AuthorType authorType;
|
||||
private String userName;
|
||||
private String roleName;
|
||||
private String password;
|
||||
//被刘昆修改,填写新的密码内容
|
||||
private String newPassword;
|
||||
private String[] privilegeList;
|
||||
private Path nodeName;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getRoleName() {
|
||||
return roleName;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public String getPassWord() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassWord(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
|
||||
public String[] getPrivilegeList() {
|
||||
return privilegeList;
|
||||
}
|
||||
|
||||
public void setPrivilegeList(String[] authorizationList) {
|
||||
this.privilegeList = authorizationList;
|
||||
}
|
||||
|
||||
public Path getNodeName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
public void setNodeNameList(String[] nodeNameList) {
|
||||
StringContainer sc = new StringContainer(SQLConstant.PATH_SEPARATOR);
|
||||
sc.addTail(nodeNameList);
|
||||
this.nodeName = new Path(sc);
|
||||
}
|
||||
|
||||
public enum AuthorType {
|
||||
CREATE_USER, CREATE_ROLE, DROP_USER, DROP_ROLE, GRANT_ROLE, GRANT_USER, GRANT_ROLE_TO_USER, REVOKE_USER, REVOKE_ROLE, REVOKE_ROLE_FROM_USER,UPDATE_USER
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
return new AuthorPlan(authorType, userName, roleName, password, newPassword, privilegeList, nodeName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.utils.Pair;
|
||||
import cn.edu.thu.tsfile.file.metadata.enums.TSDataType;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterFactory;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.SingleSeriesFilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.filterseries.FilterSeriesType;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.BasicOperatorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpSelectFromException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpWhereException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.SeriesNotExistException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.BasicOperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.FilterType;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
|
||||
/**
|
||||
* basic operator include < > >= <= !=.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
|
||||
public class BasicFunctionOperator extends FunctionOperator {
|
||||
Logger LOG = LoggerFactory.getLogger(BasicFunctionOperator.class);
|
||||
|
||||
private BasicOperatorType funcToken;
|
||||
private final FilterType filterType;
|
||||
|
||||
protected Path seriesPath;
|
||||
protected String seriesValue;
|
||||
|
||||
public String getSeriesPath() {
|
||||
return seriesPath.toString();
|
||||
}
|
||||
|
||||
public String getSeriesValue() {
|
||||
return seriesValue;
|
||||
}
|
||||
|
||||
public BasicFunctionOperator(int tokenIntType, Path path, String value)
|
||||
throws BasicOperatorException {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.BASIC_FUNC;
|
||||
funcToken = BasicOperatorType.getBasicOpBySymbol(tokenIntType);
|
||||
this.seriesPath = this.singlePath = path;
|
||||
this.seriesValue = value;
|
||||
filterType = FilterType.valueOfStr(seriesPath.getFullPath());
|
||||
|
||||
}
|
||||
|
||||
public void setReversedTokenIntType() throws BasicOperatorException {
|
||||
int intType = SQLConstant.reverseWords.get(tokenIntType);
|
||||
setTokenIntType(intType);
|
||||
funcToken = BasicOperatorType.getBasicOpBySymbol(intType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getSinglePath() {
|
||||
return singlePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHeadDeltaObjectPath(String deltaObject) {
|
||||
seriesPath.addHeadPath(deltaObject);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Pair<Map<String, FilterOperator>, FilterOperator> splitFilOpWithDNF(
|
||||
// Set<String> reservedWords){
|
||||
// Map<String, FilterOperator> ret = new HashMap<String, FilterOperator>();
|
||||
// if(reservedWords.contains(seriesPath.toString())){
|
||||
// ret.put(seriesPath.toString(), this);
|
||||
// return new Pair<Map<String,FilterOperator>, FilterOperator>(ret, null);
|
||||
// }
|
||||
// else {
|
||||
// return new Pair<Map<String,FilterOperator>, FilterOperator>(ret, this);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected Pair<SingleSeriesFilterExpression, String> transformToSingleFilter(QueryProcessExecutor exec)
|
||||
throws QpSelectFromException, QpWhereException {
|
||||
TSDataType type = exec.getSeriesType(seriesPath);
|
||||
if (type == null) {
|
||||
throw new SeriesNotExistException("given path:{" + seriesPath.getFullPath()
|
||||
+ "} don't exist in metadata");
|
||||
}
|
||||
SingleSeriesFilterExpression ret = null;
|
||||
switch (type) {
|
||||
case INT32:
|
||||
ret =
|
||||
funcToken.getSingleSeriesFilterExpression(
|
||||
FilterFactory.intFilterSeries(seriesPath.getDeltaObjectToString(),
|
||||
seriesPath.getMeasurementToString(), FilterSeriesType.VALUE_FILTER),
|
||||
Integer.valueOf(seriesValue));
|
||||
break;
|
||||
case INT64:
|
||||
ret =
|
||||
funcToken.getSingleSeriesFilterExpression(
|
||||
FilterFactory.longFilterSeries(seriesPath.getDeltaObjectToString(),
|
||||
seriesPath.getMeasurementToString(), FilterSeriesType.VALUE_FILTER),
|
||||
Long.valueOf(seriesValue));
|
||||
break;
|
||||
case BOOLEAN:
|
||||
ret =
|
||||
funcToken.getSingleSeriesFilterExpression(
|
||||
FilterFactory.booleanFilterSeries(seriesPath.getDeltaObjectToString(),
|
||||
seriesPath.getMeasurementToString(), FilterSeriesType.VALUE_FILTER),
|
||||
Boolean.valueOf(seriesValue));
|
||||
break;
|
||||
case FLOAT:
|
||||
ret =
|
||||
funcToken.getSingleSeriesFilterExpression(
|
||||
FilterFactory.floatFilterSeries(seriesPath.getDeltaObjectToString(),
|
||||
seriesPath.getMeasurementToString(), FilterSeriesType.VALUE_FILTER),
|
||||
Float.valueOf(seriesValue));
|
||||
break;
|
||||
case DOUBLE:
|
||||
ret =
|
||||
funcToken.getSingleSeriesFilterExpression(
|
||||
FilterFactory.doubleFilterSeries(seriesPath.getDeltaObjectToString(),
|
||||
seriesPath.getMeasurementToString(), FilterSeriesType.VALUE_FILTER),
|
||||
Double.valueOf(seriesValue));
|
||||
break;
|
||||
default:
|
||||
throw new QpWhereException("unsupported data type:" + type);
|
||||
}
|
||||
return new Pair<SingleSeriesFilterExpression, String>(ret, seriesPath.getFullPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String showTree(int spaceNum) {
|
||||
StringContainer sc = new StringContainer();
|
||||
for (int i = 0; i < spaceNum; i++) {
|
||||
sc.addTail(" ");
|
||||
}
|
||||
sc.addTail(seriesPath.toString(), this.tokenSymbol, seriesValue, ", single\n");
|
||||
return sc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicFunctionOperator clone() {
|
||||
BasicFunctionOperator ret;
|
||||
try {
|
||||
ret = new BasicFunctionOperator(this.tokenIntType, seriesPath.clone(), seriesValue);
|
||||
} catch (BasicOperatorException e) {
|
||||
LOG.error("error clone:{}",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
ret.tokenSymbol=tokenSymbol;
|
||||
ret.isLeaf = isLeaf;
|
||||
ret.isSingle = isSingle;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "["+seriesPath.getFullPath()+tokenSymbol+seriesValue+"]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.LESSTHAN;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.LESSTHANOREQUALTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.ParseTimeException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpSelectFromException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.DeletePlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* this class extends {@code RootOperator} and process delete statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class DeleteOperator extends SFWOperator {
|
||||
private static Logger LOG = LoggerFactory.getLogger(DeleteOperator.class);
|
||||
|
||||
public DeleteOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
DeletePlan delPlan = new DeletePlan();
|
||||
// thansform where condition to Filter class
|
||||
// for update, delete and insert, all where clause has just condition about time
|
||||
parseDeleteTimeFilter(delPlan);
|
||||
// parse path
|
||||
List<Path> paths = getSelSeriesPaths(conf);
|
||||
if (paths.size() != 1) {
|
||||
throw new QpSelectFromException(
|
||||
"for delete command, cannot specified more than one path:" + paths);
|
||||
}
|
||||
delPlan.setPath(paths.get(0));
|
||||
return delPlan;
|
||||
}
|
||||
|
||||
/**
|
||||
* for delete command, time should have start and end time range.
|
||||
*
|
||||
* @param delPlan
|
||||
*/
|
||||
private void parseDeleteTimeFilter(DeletePlan delPlan) throws ParseTimeException {
|
||||
if (!(filterOperator.isLeaf)) {
|
||||
// LOG.error("for delete command, where clause must be like : time < XXXX");
|
||||
throw new ParseTimeException(
|
||||
"for delete command, where clause must be like : time < XXX");
|
||||
}
|
||||
|
||||
if (filterOperator.getTokenIntType() != LESSTHAN
|
||||
&& filterOperator.getTokenIntType() != LESSTHANOREQUALTO) {
|
||||
// LOG.error(
|
||||
// "for delete command, time filter must be less than or less than or equal to, this:{}",
|
||||
// filterOperator.getTokenIntType());
|
||||
// return false;
|
||||
throw new ParseTimeException(
|
||||
"for delete command, time filter must be less than or less than or equal to, this:"
|
||||
+ filterOperator.getTokenIntType());
|
||||
}
|
||||
long delTime = Long.valueOf(((BasicFunctionOperator) filterOperator).getSeriesValue());
|
||||
|
||||
if (delTime < 0) {
|
||||
// LOG.error("delete Time:{}, time filter error", delTime);
|
||||
// return false;
|
||||
throw new ParseTimeException("delete Time:" + delTime + ", time filter error");
|
||||
}
|
||||
delPlan.setDeleteTime(delTime);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_AND;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_OR;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.utils.Pair;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterFactory;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.SingleSeriesFilterExpression;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.FilterOperatorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
/**
|
||||
* This class is for filter operator and implements
|
||||
* {@link cn.edu.thu.tsfiledb.qp.logical.operator.Operator} .<br>
|
||||
* it may consist of more than two child FilterOperator, but if it's not leaf operator, the relation
|
||||
* is same among all of its children.(AND or OR). It's identified by tokenType.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class FilterOperator extends Operator implements Comparable<FilterOperator> {
|
||||
Logger LOG = LoggerFactory.getLogger(FilterOperator.class);
|
||||
// it is the symbol of token. e.g. AND is & and OR is |
|
||||
protected String tokenSymbol;
|
||||
|
||||
protected List<FilterOperator> childOperators;
|
||||
// leaf filter operator means it doesn't have left and right child filterOperator. Leaf filter
|
||||
// should set FunctionOperator.
|
||||
protected boolean isLeaf = false;
|
||||
// isSingle being true means all recursive children of this filter belong to one series path.
|
||||
protected boolean isSingle = false;
|
||||
// if isSingle = false, singlePath must be null
|
||||
protected Path singlePath = null;
|
||||
|
||||
public void addHeadDeltaObjectPath(String deltaObject) {
|
||||
for (FilterOperator child : childOperators) {
|
||||
child.addHeadDeltaObjectPath(deltaObject);
|
||||
}
|
||||
if(isSingle)
|
||||
this.singlePath.addHeadPath(deltaObject);
|
||||
}
|
||||
|
||||
public FilterOperator(int tokenType) {
|
||||
super(tokenType);
|
||||
operatorType = OperatorType.FILTER;
|
||||
childOperators = new ArrayList<FilterOperator>();
|
||||
this.tokenIntType = tokenType;
|
||||
isLeaf = false;
|
||||
tokenSymbol = SQLConstant.tokenSymbol.get(tokenType);
|
||||
}
|
||||
|
||||
public void setTokenIntType(int intType) {
|
||||
this.tokenIntType = intType;
|
||||
this.tokenName = SQLConstant.tokenNames.get(tokenIntType);
|
||||
this.tokenSymbol = SQLConstant.tokenSymbol.get(tokenIntType);
|
||||
}
|
||||
|
||||
public FilterOperator(int tokenType, boolean isSingle) {
|
||||
this(tokenType);
|
||||
this.isSingle = isSingle;
|
||||
}
|
||||
|
||||
public int getTokenIntType() {
|
||||
return tokenIntType;
|
||||
}
|
||||
|
||||
public List<FilterOperator> getChildren() {
|
||||
return childOperators;
|
||||
}
|
||||
|
||||
public void setChildrenList(List<FilterOperator> children) {
|
||||
this.childOperators = children;
|
||||
}
|
||||
|
||||
public void setIsSingle(boolean b) {
|
||||
this.isSingle = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this node's singlePath is set, this.isLeaf will be set true in same time
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
public void setSinglePath(Path p) {
|
||||
this.singlePath = p;
|
||||
}
|
||||
|
||||
public Path getSinglePath() {
|
||||
return singlePath;
|
||||
}
|
||||
|
||||
public boolean addChildOPerator(FilterOperator op) {
|
||||
childOperators.add((FilterOperator) op);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For a filter operator, if isSingle, call transformToSingleFilter.<br>
|
||||
* FilterOperator cannot be leaf.
|
||||
*
|
||||
* @return
|
||||
* @throws QueryProcessorException
|
||||
*/
|
||||
public FilterExpression transformToFilter(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
if (isSingle) {
|
||||
Pair<SingleSeriesFilterExpression, String> ret = transformToSingleFilter(conf);
|
||||
return ret.left;
|
||||
} else {
|
||||
if (childOperators.isEmpty()) {
|
||||
throw new FilterOperatorException("this filter is not leaf, but it's empty:"
|
||||
+ tokenIntType);
|
||||
}
|
||||
FilterExpression retFilter = childOperators.get(0).transformToFilter(conf);
|
||||
FilterExpression cross;
|
||||
for (int i = 1; i < childOperators.size(); i++) {
|
||||
cross = childOperators.get(i).transformToFilter(conf);
|
||||
switch (tokenIntType) {
|
||||
case KW_AND:
|
||||
retFilter = FilterFactory.and(retFilter, cross);
|
||||
break;
|
||||
case KW_OR:
|
||||
retFilter = FilterFactory.or(retFilter, cross);
|
||||
break;
|
||||
default:
|
||||
throw new FilterOperatorException("unknown binary tokenIntType:"
|
||||
+ tokenIntType + ",maybe it means "
|
||||
+ SQLConstant.tokenNames.get(tokenIntType));
|
||||
}
|
||||
}
|
||||
return retFilter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* it will be used in BasicFunction Operator
|
||||
*
|
||||
* @param exec
|
||||
* @return - pair.left:SingleSeriesFilterExpression constructed by its one child; - pair.right: Path
|
||||
* represented by this child.
|
||||
* @throws QueryProcessorException
|
||||
*/
|
||||
protected Pair<SingleSeriesFilterExpression, String> transformToSingleFilter(QueryProcessExecutor exec)
|
||||
throws QueryProcessorException {
|
||||
if (childOperators.isEmpty()) {
|
||||
throw new FilterOperatorException(
|
||||
("transformToSingleFilter: this filter is not leaf, but it's empty:{}" + tokenIntType));
|
||||
}
|
||||
Pair<SingleSeriesFilterExpression, String> single =
|
||||
childOperators.get(0).transformToSingleFilter(exec);
|
||||
SingleSeriesFilterExpression retFilter = single.left;
|
||||
String childSeriesStr = single.right;
|
||||
//
|
||||
for (int i = 1; i < childOperators.size(); i++) {
|
||||
single = childOperators.get(i).transformToSingleFilter(exec);
|
||||
if (!childSeriesStr.equals(single.right))
|
||||
throw new FilterOperatorException(
|
||||
("transformToSingleFilter: paths among children are not inconsistent: one is:"
|
||||
+ childSeriesStr + ",another is:" + single.right));
|
||||
switch (tokenIntType) {
|
||||
case KW_AND:
|
||||
retFilter = (SingleSeriesFilterExpression) FilterFactory.and(retFilter, single.left);
|
||||
break;
|
||||
case KW_OR:
|
||||
retFilter = (SingleSeriesFilterExpression) FilterFactory.or(retFilter, single.left);
|
||||
break;
|
||||
default:
|
||||
throw new FilterOperatorException("unknown binary tokenIntType:"
|
||||
+ tokenIntType + ",maybe it means "
|
||||
+ SQLConstant.tokenNames.get(tokenIntType));
|
||||
}
|
||||
}
|
||||
return new Pair<SingleSeriesFilterExpression, String>(retFilter, childSeriesStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* if this is null, ordered to later
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(FilterOperator fil) {
|
||||
if (singlePath == null && fil.singlePath == null) {
|
||||
return 0;
|
||||
}
|
||||
if (singlePath == null) {
|
||||
return 1;
|
||||
}
|
||||
if (fil.singlePath == null) {
|
||||
return -1;
|
||||
}
|
||||
return fil.singlePath.toString().compareTo(singlePath.toString());
|
||||
}
|
||||
|
||||
public boolean isLeaf() {
|
||||
return isLeaf;
|
||||
}
|
||||
|
||||
public boolean isSingle() {
|
||||
return isSingle;
|
||||
}
|
||||
|
||||
public String showTree() {
|
||||
return showTree(0);
|
||||
}
|
||||
|
||||
public String showTree(int spaceNum) {
|
||||
StringContainer sc = new StringContainer();
|
||||
for (int i = 0; i < spaceNum; i++) {
|
||||
sc.addTail(" ");
|
||||
}
|
||||
sc.addTail(this.tokenName);
|
||||
if (isSingle) {
|
||||
sc.addTail("[single:", getSinglePath().toString(), "]");
|
||||
}
|
||||
sc.addTail("\n");
|
||||
for (FilterOperator filter : childOperators) {
|
||||
sc.addTail(filter.showTree(spaceNum + 1));
|
||||
}
|
||||
return sc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringContainer sc = new StringContainer();
|
||||
sc.addTail("[", this.tokenName);
|
||||
if (isSingle) {
|
||||
sc.addTail("[single:", getSinglePath().toString(), "]");
|
||||
}
|
||||
sc.addTail(" ");
|
||||
for (FilterOperator filter : childOperators) {
|
||||
sc.addTail(filter.toString());
|
||||
}
|
||||
sc.addTail("]");
|
||||
return sc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilterOperator clone() {
|
||||
FilterOperator ret = new FilterOperator(this.tokenIntType);
|
||||
ret.tokenSymbol=tokenSymbol;
|
||||
ret.isLeaf = isLeaf;
|
||||
ret.isSingle = isSingle;
|
||||
if(singlePath != null)
|
||||
ret.singlePath = singlePath.clone();
|
||||
for (FilterOperator filterOperator : this.childOperators) {
|
||||
ret.addChildOPerator(filterOperator.clone());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.utils.Pair;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpSelectFromException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
|
||||
/**
|
||||
* this class maintains information from {@code FROM} clause
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class FromOperator extends Operator {
|
||||
Logger LOG = LoggerFactory.getLogger(FromOperator.class);
|
||||
private List<Path> prefixList;
|
||||
|
||||
public FromOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.FROM;
|
||||
prefixList = new ArrayList<Path>();
|
||||
}
|
||||
|
||||
public void addPrefixTablePath(Path prefixPath) throws QpSelectFromException {
|
||||
// if(!prefixPath.startWith(SQLConstant.ROOT))
|
||||
// throw new QpSelectFromException("given select clause path doesn't start with ROOT!");
|
||||
prefixList.add(prefixPath);
|
||||
}
|
||||
|
||||
// public void addPrefixTablePath(String[] prefixPath) {
|
||||
// addPrefixTablePath(new StringContainer(prefixPath, SQLConstant.PATH_SEPARATER));
|
||||
// }
|
||||
|
||||
public List<Path> getPrefixPaths() {
|
||||
return prefixList;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Pair<path. alias>}
|
||||
*
|
||||
* @return not be null, just empty list
|
||||
*/
|
||||
public List<Pair<Path, String>> getPathsAndAlias() {
|
||||
// TODO up to now(2016-11-14), we don't involve alias, thus set alias to null
|
||||
List<Pair<Path, String>> ret = new ArrayList<Pair<Path, String>>();
|
||||
for (Path path: prefixList) {
|
||||
ret.add(new Pair<Path, String>(path, null));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.utils.Pair;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
|
||||
/**
|
||||
* This class presents series condition which is general(e.g. numerical comparison) or defined by
|
||||
* user. Function is used for bottom operator.<br>
|
||||
* FunctionOperator has a {@code seriesPath}, and other filter condition.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
|
||||
public class FunctionOperator extends FilterOperator {
|
||||
Logger LOG = LoggerFactory.getLogger(FunctionOperator.class);
|
||||
|
||||
public FunctionOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.FUNC;
|
||||
isLeaf = true;
|
||||
isSingle = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addChildOPerator(FilterOperator op) {
|
||||
LOG.error("cannot add child to leaf FilterOperator, now it's FunctionOperator");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For function Operator, it just return itself expression and its path.
|
||||
*
|
||||
* @param reserveWordsMap
|
||||
* @return {@code <reservedWord, expression>}
|
||||
*/
|
||||
public Pair<String, StringContainer> getFilterToStr() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* return seriesPath
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSeriesPath() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
/**
|
||||
* This class is used for GROUP clause(not used up to now).
|
||||
*
|
||||
* @since 2016-09-27 16:03:45
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class GroupByOperator extends Operator {
|
||||
|
||||
public GroupByOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.GROUPBY;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.TSTransformException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.InsertPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* this class extends {@code RootOperator} and process insert statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class InsertOperator extends SFWOperator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InsertOperator.class);
|
||||
private long insertTime;
|
||||
private String insertValue;
|
||||
|
||||
public InsertOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.INSERT;
|
||||
}
|
||||
|
||||
|
||||
public void setInsertValue(String value) {
|
||||
insertValue = value;
|
||||
}
|
||||
|
||||
public void setInsertTime(long time) {
|
||||
insertTime = Long.valueOf(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
InsertPlan insertPlan = new InsertPlan();
|
||||
insertPlan.setTime(insertTime);
|
||||
// parse value
|
||||
insertPlan.setValue(insertValue);
|
||||
// parse path
|
||||
List<Path> paths = getSelSeriesPaths(conf);
|
||||
if (paths.size() != 1) {
|
||||
throw new TSTransformException("for insert command, cannot specified more than one path:{}"+ paths);
|
||||
}
|
||||
insertPlan.setPath(paths.get(0));
|
||||
return insertPlan;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.TSTransformException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.InsertPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.MultiInsertPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* this class extends {@code RootOperator} and process insert statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MultiInsertOperator extends SFWOperator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MultiInsertOperator.class);
|
||||
private long insertTime;
|
||||
private List<String> measurementList;
|
||||
private List<String> insertValue;
|
||||
|
||||
|
||||
public MultiInsertOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.MULTIINSERT;
|
||||
}
|
||||
|
||||
public void setInsertTime(long time) {
|
||||
insertTime = Long.valueOf(time);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
List<Path> paths = getSelSeriesPaths(conf);
|
||||
if(paths.size() != 1){
|
||||
throw new TSTransformException("for MultiInsert command, cannot specified more than one path:{}"+ paths);
|
||||
}
|
||||
Path deltaObject = paths.get(0);
|
||||
MultiInsertPlan multiInsertPlan = new MultiInsertPlan(deltaObject.getFullPath(), insertTime, measurementList, insertValue);
|
||||
return multiInsertPlan;
|
||||
}
|
||||
|
||||
public List<String> getMeasurementList() {
|
||||
return measurementList;
|
||||
}
|
||||
|
||||
public void setMeasurementList(List<String> measurementList) {
|
||||
this.measurementList = measurementList;
|
||||
}
|
||||
|
||||
public List<String> getInsertValue() {
|
||||
return insertValue;
|
||||
}
|
||||
|
||||
public void setInsertValue(List<String> insertValue) {
|
||||
this.insertValue = insertValue;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_AND;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_OR;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QueryOperatorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.query.MergeQuerySetPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.query.SeriesSelectPlan;
|
||||
|
||||
|
||||
/**
|
||||
* this class extends {@code RootOperator} and process getIndex statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class QueryOperator extends SFWOperator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(QueryOperator.class);
|
||||
|
||||
public QueryOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.QUERY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
List<Path> paths = getSelSeriesPaths(conf);
|
||||
String aggregation = selectOperator.getAggregation();
|
||||
if(aggregation != null)
|
||||
conf.addParameter(SQLConstant.IS_AGGREGATION, aggregation);
|
||||
ArrayList<SeriesSelectPlan> subPlans = new ArrayList<SeriesSelectPlan>();
|
||||
if (filterOperator == null) {
|
||||
subPlans.add(new SeriesSelectPlan(paths, null, null, null, conf));
|
||||
}
|
||||
else{
|
||||
List<FilterOperator> parts = splitFilter();
|
||||
for (FilterOperator filterOperator : parts) {
|
||||
SeriesSelectPlan plan = constructSelectPlan(filterOperator, paths, conf);
|
||||
if (plan != null)
|
||||
subPlans.add(plan);
|
||||
}
|
||||
}
|
||||
return new MergeQuerySetPlan(subPlans);
|
||||
}
|
||||
|
||||
private SeriesSelectPlan constructSelectPlan(FilterOperator filterOperator, List<Path> paths,
|
||||
QueryProcessExecutor conf) throws QueryProcessorException {
|
||||
FilterOperator timeFilter = null;
|
||||
FilterOperator freqFilter = null;
|
||||
FilterOperator valueFilter = null;
|
||||
FilterOperator deltaObjectFilterOperator = null;
|
||||
List<FilterOperator> singleFilterList;
|
||||
if (filterOperator.isSingle) {
|
||||
singleFilterList = new ArrayList<FilterOperator>();
|
||||
singleFilterList.add(filterOperator);
|
||||
} else if (filterOperator.getTokenIntType() == KW_AND) {
|
||||
// now it has been dealt with merge optimizer, thus all nodes with same path have been
|
||||
// merged to one node
|
||||
singleFilterList = filterOperator.childOperators;
|
||||
} else {
|
||||
throw new QueryOperatorException(
|
||||
"for one tasks, filter cannot be OR if it's not single");
|
||||
}
|
||||
List<FilterOperator> valueList = new ArrayList<FilterOperator>();
|
||||
Map<String, String> deltaMeasurementMap = new HashMap<String, String>();
|
||||
for (FilterOperator child : singleFilterList) {
|
||||
if (!child.isSingle) {
|
||||
throw new QueryOperatorException(
|
||||
"in format:[(a) and () and ()] or [] or [], a is not single! a:" + child);
|
||||
}
|
||||
switch (child.singlePath.toString()) {
|
||||
case SQLConstant.RESERVED_TIME:
|
||||
if (timeFilter != null) {
|
||||
throw new QueryOperatorException(
|
||||
"time filter has been specified more than once");
|
||||
}
|
||||
timeFilter = child;
|
||||
break;
|
||||
case SQLConstant.RESERVED_FREQ:
|
||||
if (freqFilter != null) {
|
||||
throw new QueryOperatorException(
|
||||
"freq filter has been specified more than once");
|
||||
}
|
||||
freqFilter = child;
|
||||
break;
|
||||
case SQLConstant.RESERVED_DELTA_OBJECT:
|
||||
if (deltaObjectFilterOperator != null) {
|
||||
throw new QueryOperatorException(
|
||||
"delta object filter has been specified more than once");
|
||||
}
|
||||
deltaObjectFilterOperator = child;
|
||||
break;
|
||||
default:
|
||||
valueList.add(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (valueList.size() == 1) {
|
||||
valueFilter = valueList.get(0);
|
||||
} else if (valueList.size() > 1) {
|
||||
valueFilter = new FilterOperator(KW_AND, false);
|
||||
valueFilter.childOperators = valueList;
|
||||
}
|
||||
|
||||
return new SeriesSelectPlan(paths, deltaObjectFilterOperator, timeFilter, freqFilter, valueFilter, conf);
|
||||
}
|
||||
|
||||
/**
|
||||
* split filter operator to a list of filter with relation of "or" each other.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<FilterOperator> splitFilter() {
|
||||
List<FilterOperator> ret = new ArrayList<FilterOperator>();
|
||||
if (filterOperator.isSingle || filterOperator.getTokenIntType() != KW_OR) {
|
||||
// single or leaf(BasicFunction)
|
||||
ret.add(filterOperator);
|
||||
return ret;
|
||||
}
|
||||
// a list of partion linked with or
|
||||
return filterOperator.childOperators;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpSelectFromException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
|
||||
/**
|
||||
* SFWOperator includes four subclass: INSERT,DELETE,UPDATE,QUERY. All of these four statements has
|
||||
* three partition: select clause, from clause and filter clause(where clause).
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public abstract class SFWOperator extends RootOperator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SFWOperator.class);
|
||||
|
||||
protected SelectOperator selectOperator;
|
||||
protected FromOperator fromOperator;
|
||||
protected FilterOperator filterOperator;
|
||||
|
||||
public SFWOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.ROOT;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * transform this root operator tree to a physical plan tree.Node that, before this method
|
||||
// * called, the where filter has been dealt with
|
||||
// * {@linkplain com.corp.tsfile.qp.logical.optimizer.filter.MergeSingleFilterOptimizer}
|
||||
// *
|
||||
// */
|
||||
// public abstract PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
// throws QueryProcessorException;
|
||||
|
||||
public void setSelectOperator(SelectOperator sel) {
|
||||
this.selectOperator = sel;
|
||||
}
|
||||
|
||||
public void setFromOperator(FromOperator from) {
|
||||
this.fromOperator = from;
|
||||
}
|
||||
|
||||
public FromOperator getFrom() {
|
||||
return fromOperator;
|
||||
}
|
||||
|
||||
public SelectOperator getSelect() {
|
||||
return selectOperator;
|
||||
}
|
||||
|
||||
public void setFilterOperator(FilterOperator filter) {
|
||||
this.filterOperator = filter;
|
||||
}
|
||||
|
||||
public FilterOperator getFilter() {
|
||||
return filterOperator;
|
||||
}
|
||||
|
||||
/**
|
||||
* get information from SelectOperator and FromOperator and generate all table paths. <b>Note
|
||||
* that</b>, if there are some path doesn't exist in metadata tree or file metadata, this method
|
||||
* just log error records and <b>omit</b> them. Nevertheless, if all of paths doesn't exist, it
|
||||
* will throw <b>Exception</b>.
|
||||
*
|
||||
* @return - a list of path
|
||||
* @throws QpSelectFromException
|
||||
*/
|
||||
public List<Path> getSelSeriesPaths(QueryProcessExecutor qpConfig) throws QpSelectFromException {
|
||||
List<Path> prefixPaths = null;
|
||||
if (fromOperator != null) {
|
||||
prefixPaths = fromOperator.getPrefixPaths();
|
||||
// check legality of from clauses
|
||||
if (!qpConfig.isSingleFile()) {
|
||||
for (Path path : prefixPaths) {
|
||||
if (!path.startWith(SQLConstant.ROOT))
|
||||
throw new QpSelectFromException(
|
||||
"given select clause path doesn't start with ROOT!" + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
// after ConcatPathOptimizer, paths in FROM clause are just used to check legality for delta
|
||||
// system
|
||||
List<Path> suffixPaths = null;
|
||||
if (selectOperator != null)
|
||||
suffixPaths = selectOperator.getSuffixPaths();
|
||||
if ((suffixPaths == null || suffixPaths.isEmpty())) {
|
||||
// Log.error("from clause and select clause cannot be both empty!");
|
||||
throw new QpSelectFromException("select clause cannot be empty!");
|
||||
}
|
||||
else
|
||||
return suffixPaths;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
/**
|
||||
* this class maintains information from select clause
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public final class SelectOperator extends Operator {
|
||||
private List<Path> suffixList;
|
||||
private String aggregation;
|
||||
public SelectOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.SELECT;
|
||||
suffixList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addSuffixTablePath(Path suffixPath) {
|
||||
suffixList.add(suffixPath);
|
||||
}
|
||||
|
||||
public void addSuffixTablePath(Path suffixPath, String aggregation) {
|
||||
suffixList.add(suffixPath);
|
||||
this.aggregation = aggregation;
|
||||
}
|
||||
|
||||
public String getAggregation(){
|
||||
return this.aggregation;
|
||||
}
|
||||
|
||||
public void setSuffixPathList(List<Path> suffixPaths) {
|
||||
suffixList = suffixPaths;
|
||||
}
|
||||
|
||||
// public void addSuffixTablePath(String[] suffixPath) {
|
||||
// addSuffixTablePath(new StringContainer(suffixPath, SQLConstant.PATH_SEPARATER));
|
||||
// }
|
||||
|
||||
public List<Path> getSuffixPaths() {
|
||||
return suffixList;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.crud;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.GREATERTHAN;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.GREATERTHANOREQUALTO;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.LESSTHAN;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.LESSTHANOREQUALTO;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.RESERVED_TIME;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.BasicOperatorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.ParseTimeException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.QpSelectFromException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.UpdatePlan;
|
||||
|
||||
/**
|
||||
* this class extends {@code RootOperator} and process update statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public final class UpdateOperator extends SFWOperator {
|
||||
private String value;
|
||||
|
||||
public UpdateOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.UPDATE;
|
||||
}
|
||||
|
||||
public void setUpdateValue(String value) throws BasicOperatorException {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
UpdatePlan upPlan = new UpdatePlan();
|
||||
// thansform where condition to Filter class
|
||||
// for update, delete and insert, all where clause has just condition about time
|
||||
parseUpdateTimeFilter(upPlan);
|
||||
// parse value
|
||||
upPlan.setValue(value);
|
||||
// parse path
|
||||
List<Path> paths = getSelSeriesPaths(conf);
|
||||
if (paths.size() != 1) {
|
||||
throw new QpSelectFromException("update command, must have and only have one path:"
|
||||
+ paths);
|
||||
// LOG.error("for update command, cannot specified more than one path:{}", paths);
|
||||
}
|
||||
upPlan.setPath(paths.get(0));
|
||||
return upPlan;
|
||||
}
|
||||
|
||||
/**
|
||||
* for udpate command, time should have start and end time range.
|
||||
*
|
||||
* @param upPlan
|
||||
*/
|
||||
private void parseUpdateTimeFilter(UpdatePlan upPlan) throws ParseTimeException {
|
||||
if (!filterOperator.isSingle || !filterOperator.getSinglePath().equals(RESERVED_TIME)) {
|
||||
throw new ParseTimeException(
|
||||
"for update command, it has non-time condition in where clause");
|
||||
}
|
||||
if (filterOperator.childOperators.size() != 2)
|
||||
throw new ParseTimeException(
|
||||
"for update command, time must have left and right boundaries");
|
||||
FilterOperator leftOp = filterOperator.childOperators.get(0);
|
||||
FilterOperator rightOp = filterOperator.childOperators.get(1);
|
||||
if (!leftOp.isLeaf || !rightOp.isLeaf)
|
||||
throw new ParseTimeException("illegal time condition:" + filterOperator.showTree());
|
||||
long startTime = -1;
|
||||
long endTime = -1;
|
||||
// left time border
|
||||
|
||||
if (leftOp.getTokenIntType() == LESSTHAN || leftOp.getTokenIntType() == LESSTHANOREQUALTO) {
|
||||
endTime = Long.valueOf(((BasicFunctionOperator) leftOp).getSeriesValue());
|
||||
} else if (leftOp.getTokenIntType() == GREATERTHAN
|
||||
|| leftOp.getTokenIntType() == GREATERTHANOREQUALTO) {
|
||||
startTime = Long.valueOf(((BasicFunctionOperator) leftOp).getSeriesValue());
|
||||
}
|
||||
if(leftOp.getTokenIntType() == LESSTHAN){
|
||||
endTime --;
|
||||
}
|
||||
if(leftOp.getTokenIntType() == GREATERTHAN && startTime < Long.MAX_VALUE){
|
||||
startTime ++;
|
||||
}
|
||||
// right time border
|
||||
if (rightOp.getTokenIntType() == LESSTHAN || rightOp.getTokenIntType() == LESSTHANOREQUALTO) {
|
||||
endTime = Long.valueOf(((BasicFunctionOperator) rightOp).getSeriesValue());
|
||||
} else if (rightOp.getTokenIntType() == GREATERTHAN
|
||||
|| rightOp.getTokenIntType() == GREATERTHANOREQUALTO) {
|
||||
startTime = Long.valueOf(((BasicFunctionOperator) rightOp).getSeriesValue());
|
||||
}
|
||||
if(rightOp.getTokenIntType() == LESSTHAN){
|
||||
endTime --;
|
||||
}
|
||||
if(rightOp.getTokenIntType() == GREATERTHAN && startTime < Long.MAX_VALUE){
|
||||
startTime ++;
|
||||
}
|
||||
|
||||
if (startTime < 0 || endTime < 0) {
|
||||
// LOG.error("startTime:{},endTime:{}, one of them is illegal", startTime, endTime);
|
||||
throw new ParseTimeException("startTime:" + startTime + ",endTime:" + endTime
|
||||
+ ", one of them is illegal");
|
||||
}
|
||||
if (startTime > endTime) {
|
||||
// LOG.error("startTime:{},endTime:{}, start time cannot be greater than end time",
|
||||
// startTime, endTime);
|
||||
throw new ParseTimeException("startTime:" + startTime + ",endTime:" + endTime
|
||||
+ ", start time cannot be greater than end time");
|
||||
}
|
||||
upPlan.setStartTime(startTime);
|
||||
upPlan.setEndTime(endTime);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.load;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.LoadDataPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* this class maintains information in Author statement, including CREATE, DROP, GRANT and REVOKE
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class LoadDataOperator extends RootOperator {
|
||||
private final String inputFilePath;
|
||||
private final String measureType;
|
||||
|
||||
public LoadDataOperator(int tokenIntType, String inputFilePath, String measureType) {
|
||||
super(tokenIntType);
|
||||
operatorType = OperatorType.LOADDATA;
|
||||
this.inputFilePath = inputFilePath;
|
||||
this.measureType = measureType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
return new LoadDataPlan(inputFilePath, measureType);
|
||||
}
|
||||
|
||||
public String getInputFilePath() {
|
||||
return inputFilePath;
|
||||
}
|
||||
|
||||
public String getMeasureType() {
|
||||
return measureType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.metadata;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.metadata.MetadataPlan;
|
||||
|
||||
/**
|
||||
* this class maintains information in Metadata.namespace statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MetadataOperator extends RootOperator {
|
||||
|
||||
public MetadataOperator(int tokenIntType, NamespaceType type) {
|
||||
super(tokenIntType);
|
||||
namespaceType = type;
|
||||
operatorType = OperatorType.METADATA;
|
||||
}
|
||||
|
||||
private final NamespaceType namespaceType;
|
||||
private Path path;
|
||||
private String dataType;
|
||||
private String encoding;
|
||||
private String[] encodingArgs;
|
||||
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setDataType(String dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public String[] getEncodingArgs() {
|
||||
return encodingArgs;
|
||||
}
|
||||
|
||||
public void setEncodingArgs(String[] encodingArgs) {
|
||||
this.encodingArgs = encodingArgs;
|
||||
}
|
||||
|
||||
public NamespaceType getNamespaceType() {
|
||||
return namespaceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
return new MetadataPlan(namespaceType, path, dataType, encoding, encodingArgs);
|
||||
}
|
||||
|
||||
public static enum NamespaceType {
|
||||
ADD_PATH, DELETE_PATH, SET_FILE_LEVEL
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.metadata;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.metadata.PropertyPlan;
|
||||
|
||||
/**
|
||||
* this class maintains information in Metadata.namespace statement
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class PropertyOperator extends RootOperator {
|
||||
|
||||
public PropertyOperator(int tokenIntType, PropertyType type) {
|
||||
super(tokenIntType);
|
||||
propertyType = type;
|
||||
operatorType = OperatorType.PROPERTY;
|
||||
}
|
||||
|
||||
private final PropertyType propertyType;
|
||||
private Path propertyPath;
|
||||
private Path metadataPath;
|
||||
|
||||
public Path getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
|
||||
public void setPropertyPath(Path propertyPath) {
|
||||
this.propertyPath = propertyPath;
|
||||
}
|
||||
|
||||
public Path getMetadataPath() {
|
||||
return metadataPath;
|
||||
}
|
||||
|
||||
public void setMetadataPath(Path metadataPath) {
|
||||
this.metadataPath = metadataPath;
|
||||
}
|
||||
|
||||
public PropertyType getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
return new PropertyPlan(propertyType, propertyPath, metadataPath);
|
||||
}
|
||||
|
||||
public static enum PropertyType {
|
||||
ADD_TREE, ADD_PROPERTY_LABEL, DELETE_PROPERTY_LABEL, ADD_PROPERTY_TO_METADATA,DEL_PROPERTY_FROM_METADATA
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.sys;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
public class FlushOperator extends RootOperator{
|
||||
|
||||
public FlushOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf) throws QueryProcessorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.operator.sys;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.RootOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
public class MergeOperator extends RootOperator{
|
||||
|
||||
public MergeOperator(int tokenIntType) {
|
||||
super(tokenIntType);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transformToPhysicalPlan(QueryProcessExecutor conf) throws QueryProcessorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.utils.Pair;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.PathConcatException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.BasicFunctionOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FromOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SFWOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.SelectOperator;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class deals with delta object in union table
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class ConcatPathOptimizer implements ILogicalOptimizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConcatPathOptimizer.class);
|
||||
|
||||
@Override
|
||||
public Operator transform(Operator context) throws PathConcatException {
|
||||
if (!(context instanceof SFWOperator)) {
|
||||
LOG.warn("given operator isn't SFWOperator, cannot concat path");
|
||||
return context;
|
||||
}
|
||||
SFWOperator sfwOperator = (SFWOperator) context;
|
||||
FromOperator from = sfwOperator.getFrom();
|
||||
List<Pair<Path, String>> prefixPathPairs;
|
||||
if (from == null || (prefixPathPairs = from.getPathsAndAlias()).isEmpty()) {
|
||||
LOG.warn("given SFWOperator doesn't have prefix paths, cannot concat path");
|
||||
return context;
|
||||
}
|
||||
SelectOperator select = sfwOperator.getSelect();
|
||||
List<Path> suffixPaths;
|
||||
if (select == null || (suffixPaths = select.getSuffixPaths()).isEmpty()) {
|
||||
LOG.warn("given SFWOperator doesn't have suffix paths, cannot concat path");
|
||||
return context;
|
||||
}
|
||||
// concat select paths
|
||||
suffixPaths = concatSelect(prefixPathPairs, suffixPaths);
|
||||
select.setSuffixPathList(suffixPaths);
|
||||
// concat filter
|
||||
FilterOperator filter = sfwOperator.getFilter();
|
||||
if (filter == null)
|
||||
return context;
|
||||
concatFilter(prefixPathPairs, filter);
|
||||
// sfwOperator.setFilterOperator(filter);
|
||||
return sfwOperator;
|
||||
}
|
||||
|
||||
|
||||
private List<Path> concatSelect(List<Pair<Path, String>> fromPaths, List<Path> selectPaths)
|
||||
throws PathConcatException {
|
||||
if (fromPaths.size() == 1) {
|
||||
Pair<Path, String> fromPair = fromPaths.get(0);
|
||||
for (Path path : selectPaths) {
|
||||
if (path.startWith(fromPair.right)) {
|
||||
// replace alias to namespace path starting with ROOT
|
||||
path.replace(fromPair.right, fromPair.left);
|
||||
} else if (!path.startWith(fromPair.left)) {
|
||||
// add prefix root path
|
||||
path.addHeadPath(fromPair.left);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Path selectPath : selectPaths) {
|
||||
boolean legal = false;
|
||||
for (Pair<Path, String> fromPair : fromPaths) {
|
||||
if (selectPath.startWith(fromPair.right)) {
|
||||
// replace alias to namespace path starting with ROOT
|
||||
selectPath.replace(fromPair.right, fromPair.left);
|
||||
legal = true;
|
||||
break;
|
||||
} else if (selectPath.startWith(fromPair.left)) {
|
||||
// do nothing, mark legal
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!legal) {
|
||||
throw new PathConcatException("select path is illegal:" + selectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectPaths;
|
||||
}
|
||||
|
||||
private void concatFilter(List<Pair<Path, String>> fromPaths, FilterOperator filter)
|
||||
throws PathConcatException {
|
||||
if (!filter.isLeaf()) {
|
||||
for (FilterOperator child : filter.getChildren())
|
||||
concatFilter(fromPaths, child);
|
||||
return;
|
||||
}
|
||||
BasicFunctionOperator basic = (BasicFunctionOperator) filter;
|
||||
Path selectPath = basic.getSinglePath();
|
||||
if (SQLConstant.isReservedPath(selectPath))
|
||||
return;
|
||||
if (fromPaths.size() == 1) {
|
||||
Pair<Path, String> fromPair = fromPaths.get(0);
|
||||
if (selectPath.startWith(fromPair.right)) {
|
||||
// replace alias to namespace path starting with ROOT
|
||||
selectPath.replace(fromPair.right, fromPair.left);
|
||||
} else if (!selectPath.startWith(fromPair.left)) {
|
||||
// add prefix root path
|
||||
selectPath.addHeadPath(fromPair.left);
|
||||
}
|
||||
|
||||
} else {
|
||||
boolean legal = false;
|
||||
for (Pair<Path, String> fromPair : fromPaths) {
|
||||
if (selectPath.startWith(fromPair.right)) {
|
||||
// replace alias to namespace path starting with ROOT
|
||||
selectPath.replace(fromPair.right, fromPair.left);
|
||||
legal = true;
|
||||
break;
|
||||
} else if (selectPath.startWith(fromPair.left)) {
|
||||
// do nothing, mark legal
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!legal) {
|
||||
throw new PathConcatException("select path is illegal:" + selectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.LogicalOptimizeException;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
|
||||
/**
|
||||
* provide a context, transform it for optimization.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public interface ILogicalOptimizer {
|
||||
/**
|
||||
* input a TSPlanContext and
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public Operator transform(Operator context) throws LogicalOptimizeException;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator;
|
||||
|
||||
/**
|
||||
* This class do nothing for an input TSPlanContext.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class NoneLogicalOptimizer implements ILogicalOptimizer {
|
||||
|
||||
@Override
|
||||
public Operator transform(Operator context) {
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer.filter;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_AND;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_OR;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.DNFOptimizeException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.LogicalOptimizeException;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
|
||||
public class DNFFilterOptimizer implements IFilterOptimizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DNFFilterOptimizer.class);
|
||||
|
||||
|
||||
/**
|
||||
* get DNF(disjunctive normal form) for this filter operator tree. Before getDNF, this op tree
|
||||
* must be binary, in another word, each non-leaf node has exactly two children.
|
||||
*
|
||||
* @return
|
||||
* @throws LogicalOptimizeException
|
||||
*/
|
||||
@Override
|
||||
public FilterOperator optimize(FilterOperator filter) throws LogicalOptimizeException {
|
||||
return getDNF(filter);
|
||||
}
|
||||
|
||||
private FilterOperator getDNF(FilterOperator filter) throws DNFOptimizeException {
|
||||
if (filter.isLeaf())
|
||||
return filter;
|
||||
List<FilterOperator> childOperators = filter.getChildren();
|
||||
if (childOperators.size() != 2) {
|
||||
throw new DNFOptimizeException("node :" + filter.getTokenName() + " has "
|
||||
+ childOperators.size() + " childrean");
|
||||
|
||||
}
|
||||
FilterOperator left = getDNF(childOperators.get(0));
|
||||
FilterOperator right = getDNF(childOperators.get(1));
|
||||
List<FilterOperator> newChildrenList = new ArrayList<FilterOperator>();
|
||||
switch (filter.getTokenIntType()) {
|
||||
case KW_OR:
|
||||
addChildOpInOr(left, newChildrenList);
|
||||
addChildOpInOr(right, newChildrenList);
|
||||
break;
|
||||
case KW_AND:
|
||||
if (left.getTokenIntType() != KW_OR && right.getTokenIntType() != KW_OR) {
|
||||
addChildOpInAnd(left, newChildrenList);
|
||||
addChildOpInAnd(right, newChildrenList);
|
||||
} else {
|
||||
List<FilterOperator> leftAndChildren = getAndChild(left);
|
||||
List<FilterOperator> rightAndChildren = getAndChild(right);
|
||||
for (FilterOperator laChild : leftAndChildren) {
|
||||
for (FilterOperator raChild : rightAndChildren) {
|
||||
FilterOperator r = mergeToConjunction(laChild.clone(), raChild.clone());
|
||||
newChildrenList.add(r);
|
||||
}
|
||||
}
|
||||
filter.setTokenIntType(KW_OR);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new DNFOptimizeException("get DNF failed, this tokenType is:"
|
||||
+ filter.getTokenIntType());
|
||||
}
|
||||
filter.setChildrenList(newChildrenList);
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* used by getDNF. merge two conjunction filter operators into a conjunction.<br>
|
||||
* conjunction operator consists of {@code FunctionOperator} and inner operator which token is
|
||||
* KW_AND.<br>
|
||||
* e.g. (a and b) merge (c) is (a and b and c)
|
||||
*
|
||||
* @param b
|
||||
* @return
|
||||
* @throws DNFOptimizeException
|
||||
*/
|
||||
private FilterOperator mergeToConjunction(FilterOperator a, FilterOperator b)
|
||||
throws DNFOptimizeException {
|
||||
List<FilterOperator> retChildrenList = new ArrayList<FilterOperator>();
|
||||
addChildOpInAnd(a, retChildrenList);
|
||||
addChildOpInAnd(b, retChildrenList);
|
||||
FilterOperator ret = new FilterOperator(KW_AND, false);
|
||||
ret.setChildrenList(retChildrenList);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* used by getDNF. get conjunction node. <br>
|
||||
* If child is basic function or AND node, return a list just containing this. <br>
|
||||
* If this child is OR, return children of OR.
|
||||
*
|
||||
* @param child
|
||||
* @return
|
||||
*/
|
||||
private List<FilterOperator> getAndChild(FilterOperator child) {
|
||||
switch (child.getTokenIntType()) {
|
||||
case KW_OR:
|
||||
return child.getChildren();
|
||||
default:
|
||||
// other token type means leaf node or and
|
||||
List<FilterOperator> ret = new ArrayList<FilterOperator>();
|
||||
ret.add(child);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* used by getDNF
|
||||
*
|
||||
* @param child
|
||||
* @param newChildrenList
|
||||
* @throws LogicalOptimizeException
|
||||
*/
|
||||
private void addChildOpInAnd(FilterOperator child, List<FilterOperator> newChildrenList)
|
||||
throws DNFOptimizeException {
|
||||
if (child.isLeaf())
|
||||
newChildrenList.add(child);
|
||||
else if (child.getTokenIntType() == KW_AND)
|
||||
newChildrenList.addAll(child.getChildren());
|
||||
else {
|
||||
throw new DNFOptimizeException(
|
||||
"add all children of an OR operator to newChildrenList in AND");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* used by getDNF
|
||||
*
|
||||
* @param child
|
||||
* @param newChildrenList
|
||||
*/
|
||||
private void addChildOpInOr(FilterOperator child, List<FilterOperator> newChildrenList) {
|
||||
if (child.isLeaf() || child.getTokenIntType() == KW_AND)
|
||||
newChildrenList.add(child);
|
||||
else
|
||||
newChildrenList.addAll(child.getChildren());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer.filter;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* provide a filter operator, optimize it.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public interface IFilterOptimizer {
|
||||
public FilterOperator optimize(FilterOperator filter) throws QueryProcessorException;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.MergeFilterException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
|
||||
public class MergeSingleFilterOptimizer implements IFilterOptimizer {
|
||||
Logger LOG = LoggerFactory.getLogger(MergeSingleFilterOptimizer.class);
|
||||
|
||||
@Override
|
||||
public FilterOperator optimize(FilterOperator filter) {
|
||||
try {
|
||||
mergeSamePathFilter(filter);
|
||||
} catch (MergeFilterException e) {
|
||||
LOG.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* merge and extract node with same Path recursively. <br>
|
||||
* If a node has more than two children and some children has same paths, remove them from this
|
||||
* node and merge them to a new single node, then add the new node to this children list.<br>
|
||||
* if all recursive children of this node have same path, set this node to single node, and
|
||||
* return the same path, otherwise, throw exception;
|
||||
*
|
||||
* @param children - children is not empty.
|
||||
*
|
||||
* @return - if all recursive children of this node have same path, set this node to single
|
||||
* node, and return the same path, otherwise, throw exception;
|
||||
*/
|
||||
public Path mergeSamePathFilter(FilterOperator src) throws MergeFilterException {
|
||||
if (src.isLeaf())
|
||||
return src.getSinglePath();
|
||||
List<FilterOperator> children = src.getChildren();
|
||||
if (children.isEmpty()) {
|
||||
throw new MergeFilterException("this inner filter has no children!");
|
||||
}
|
||||
if (children.size() == 1) {
|
||||
throw new MergeFilterException("this inner filter has just one child!");
|
||||
}
|
||||
Path childPath = mergeSamePathFilter(children.get(0));
|
||||
Path tempPath;
|
||||
for (int i = 1; i < children.size(); i++) {
|
||||
tempPath = mergeSamePathFilter(children.get(i));
|
||||
// if one of children differs with others or is not single node(path = null), src's path
|
||||
// is null
|
||||
if (tempPath != null && !tempPath.equals(childPath))
|
||||
childPath = null;
|
||||
}
|
||||
if (childPath != null) {
|
||||
src.setIsSingle(true);
|
||||
src.setSinglePath(childPath.clone());
|
||||
return childPath;
|
||||
}
|
||||
// extract same node
|
||||
Collections.sort(children);
|
||||
List<FilterOperator> ret = new ArrayList<FilterOperator>();
|
||||
|
||||
List<FilterOperator> tempExtrNode = null;
|
||||
int i;
|
||||
for (i = 0; i < children.size(); i++) {
|
||||
tempPath = children.get(i).getSinglePath();
|
||||
// sorted by path, all "null" paths are at last
|
||||
if (tempPath == null) {
|
||||
// childPath = null;
|
||||
break;
|
||||
}
|
||||
if (childPath == null) {
|
||||
// first child to be add
|
||||
childPath = tempPath;
|
||||
tempExtrNode = new ArrayList<FilterOperator>();
|
||||
tempExtrNode.add(children.get(i));
|
||||
} else if (childPath.equals(tempPath)) {
|
||||
// successive next single child with same path,merge it with previous children
|
||||
tempExtrNode.add(children.get(i));
|
||||
} else {
|
||||
// not more same, add exist nodes in tempExtrNode into a new node
|
||||
// prevent make a node which has only one child.
|
||||
if (tempExtrNode.size() == 1) {
|
||||
ret.add(tempExtrNode.get(0));
|
||||
// use exist Object directly for efficiency
|
||||
tempExtrNode.set(0, children.get(i));
|
||||
childPath = tempPath;
|
||||
} else {
|
||||
// add a new inner node
|
||||
FilterOperator newFil = new FilterOperator(src.getTokenIntType(), true);
|
||||
newFil.setSinglePath(childPath.clone());
|
||||
newFil.setChildrenList(tempExtrNode);
|
||||
ret.add(newFil);
|
||||
tempExtrNode = new ArrayList<FilterOperator>();
|
||||
tempExtrNode.add(children.get(i));
|
||||
childPath = tempPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// the last several children before null has not been added to ret list.
|
||||
if (childPath != null) {
|
||||
if (tempExtrNode.size() == 1) {
|
||||
ret.add(tempExtrNode.get(0));
|
||||
} else {
|
||||
// add a new inner node
|
||||
FilterOperator newFil = new FilterOperator(src.getTokenIntType(), true);
|
||||
newFil.setSinglePath(childPath.clone());
|
||||
newFil.setChildrenList(tempExtrNode);
|
||||
ret.add(newFil);
|
||||
}
|
||||
}
|
||||
// add last null children
|
||||
for (; i < children.size(); i++) {
|
||||
ret.add(children.get(i));
|
||||
}
|
||||
if (ret.size() == 1) {
|
||||
// all children have same path, which means this src node is a single node
|
||||
src.setIsSingle(true);
|
||||
src.setSinglePath(childPath.clone());
|
||||
src.setChildrenList(ret.get(0).getChildren());
|
||||
return childPath;
|
||||
} else {
|
||||
src.setIsSingle(false);
|
||||
src.setChildrenList(ret);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package cn.edu.thu.tsfiledb.qp.logical.optimizer.filter;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_AND;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_NOT;
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.KW_OR;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.operator.BasicOperatorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.LogicalOptimizeException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.RemoveNotException;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.BasicFunctionOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
|
||||
public class RemoveNotOptimizer implements IFilterOptimizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RemoveNotOptimizer.class);
|
||||
|
||||
|
||||
/**
|
||||
* get DNF(disjunctive normal form) for this filter operator tree. Before getDNF, this op tree
|
||||
* must be binary, in another word, each non-leaf node has exactly two children.
|
||||
*
|
||||
* @return
|
||||
* @throws LogicalOptimizeException
|
||||
*/
|
||||
@Override
|
||||
public FilterOperator optimize(FilterOperator filter) throws LogicalOptimizeException {
|
||||
return removeNot(filter);
|
||||
}
|
||||
|
||||
private FilterOperator removeNot(FilterOperator filter) throws RemoveNotException {
|
||||
if (filter.isLeaf())
|
||||
return filter;
|
||||
int tokenInt = filter.getTokenIntType();
|
||||
switch (tokenInt) {
|
||||
case KW_AND:
|
||||
case KW_OR:
|
||||
// replace children in-place for efficiency
|
||||
List<FilterOperator> children = filter.getChildren();
|
||||
children.set(0, removeNot(children.get(0)));
|
||||
children.set(1, removeNot(children.get(1)));
|
||||
return filter;
|
||||
case KW_NOT:
|
||||
return reverseFilter(filter.getChildren().get(0));
|
||||
default:
|
||||
throw new RemoveNotException("Unknown token in removeNot: " + tokenInt + ","
|
||||
+ SQLConstant.tokenNames.get(tokenInt));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reverse given filter to reversed expression
|
||||
*
|
||||
* @param filter
|
||||
* @return
|
||||
* @throws QueryProcessorException
|
||||
*/
|
||||
private FilterOperator reverseFilter(FilterOperator filter) throws RemoveNotException {
|
||||
int tokenInt = filter.getTokenIntType();
|
||||
if (filter.isLeaf()) {
|
||||
try {
|
||||
((BasicFunctionOperator) filter).setReversedTokenIntType();
|
||||
} catch (BasicOperatorException e) {
|
||||
throw new RemoveNotException(
|
||||
"convert BasicFuntion to reserved meet failed: previous token:" + tokenInt
|
||||
+ "tokenName:" + SQLConstant.tokenNames.get(tokenInt));
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
switch (tokenInt) {
|
||||
case KW_AND:
|
||||
case KW_OR:
|
||||
List<FilterOperator> children = filter.getChildren();
|
||||
children.set(0, reverseFilter(children.get(0)));
|
||||
children.set(1, reverseFilter(children.get(1)));
|
||||
filter.setTokenIntType(SQLConstant.reverseWords.get(tokenInt));
|
||||
return filter;
|
||||
case KW_NOT:
|
||||
return removeNot(filter.getChildren().get(0));
|
||||
default:
|
||||
throw new RemoveNotException("Unknown token in reverseFilter: " + tokenInt + ","
|
||||
+ SQLConstant.tokenNames.get(tokenInt));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.optimizer;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
|
||||
/**
|
||||
* this class is used for optimizing operator tree in physical layer.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public interface IPhysicalOptimizer {
|
||||
public PhysicalPlan transform(PhysicalPlan context, QueryProcessExecutor conf);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.optimizer;
|
||||
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class do nothing for an input TSPlanContext.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class NonePhycicalOptimizer implements IPhysicalOptimizer {
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transform(PhysicalPlan context, QueryProcessExecutor conf) {
|
||||
return context;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.optimizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.constant.QueryConstant;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.constant.SQLConstant;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.logical.optimize.MergeFilterException;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.BasicFunctionOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.query.MergeQuerySetPlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.query.SeriesSelectPlan;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class deals with delta object in union table
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class UnionTableOptimizer implements IPhysicalOptimizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UnionTableOptimizer.class);
|
||||
private MergeQuerySetPlan plan;
|
||||
|
||||
@Override
|
||||
public PhysicalPlan transform(PhysicalPlan plan, QueryProcessExecutor conf) {
|
||||
MergeQuerySetPlan mergePlan = (MergeQuerySetPlan) plan;
|
||||
ArrayList<String> alldeltaObjects = (ArrayList<String>)conf.getParameter(QueryConstant.ALL_DEVICES);
|
||||
|
||||
for (SeriesSelectPlan seriesPlan : mergePlan.getSelectPlans()) {
|
||||
List<SeriesSelectPlan> newPlans = new ArrayList<>();
|
||||
Set<String> selectDeltaObjects = mergeDeltaObject(seriesPlan.getDeltaObjectFilterOperator());
|
||||
|
||||
ArrayList<String> actualDeltaObjects = new ArrayList<>();
|
||||
//if select deltaObject, then match with measurement
|
||||
if(selectDeltaObjects != null && selectDeltaObjects.size() >= 1) {
|
||||
actualDeltaObjects.addAll(selectDeltaObjects);
|
||||
} else {
|
||||
actualDeltaObjects.addAll(alldeltaObjects);
|
||||
}
|
||||
|
||||
FilterOperator timeFilter = seriesPlan.getTimeFilterOperator();
|
||||
FilterOperator freqFilter = seriesPlan.getFreqFilterOperator();
|
||||
FilterOperator valueFilter = seriesPlan.getValueFilterOperator();
|
||||
List<Path> paths = seriesPlan.getPaths();
|
||||
|
||||
for(String deltaObject: actualDeltaObjects) {
|
||||
List<Path> newPaths = new ArrayList<>();
|
||||
for(Path path: paths) {
|
||||
Path newPath = new Path(deltaObject + "." + path.getFullPath());
|
||||
newPaths.add(newPath);
|
||||
}
|
||||
SeriesSelectPlan newSeriesPlan;
|
||||
if(valueFilter == null) {
|
||||
newSeriesPlan = new SeriesSelectPlan(newPaths, timeFilter, freqFilter, null,conf);
|
||||
} else {
|
||||
FilterOperator newValueFilter = valueFilter.clone();
|
||||
newValueFilter.addHeadDeltaObjectPath(deltaObject);
|
||||
newSeriesPlan = new SeriesSelectPlan(newPaths, timeFilter, freqFilter, newValueFilter,conf);
|
||||
}
|
||||
newPlans.add(newSeriesPlan);
|
||||
}
|
||||
mergePlan.setSelectPlans(newPlans);
|
||||
}
|
||||
return mergePlan;
|
||||
}
|
||||
|
||||
public Set<String> mergeDeltaObject(FilterOperator deltaFilterOperator) {
|
||||
if (deltaFilterOperator == null) {
|
||||
System.out.println("deltaFilterOperator is null");
|
||||
return null;
|
||||
}
|
||||
if (deltaFilterOperator.isLeaf()) {
|
||||
Set<String> r = new HashSet<String>();
|
||||
r.add(((BasicFunctionOperator)deltaFilterOperator).getSeriesValue());
|
||||
return r;
|
||||
}
|
||||
List<FilterOperator> children = deltaFilterOperator.getChildren();
|
||||
if (children.isEmpty()) {
|
||||
return new HashSet<String>();
|
||||
}
|
||||
Set<String> ret = mergeDeltaObject(children.get(0));
|
||||
for (int i = 1; i < children.size(); i++) {
|
||||
Set<String> temp = mergeDeltaObject(children.get(i));
|
||||
switch (deltaFilterOperator.getTokenIntType()) {
|
||||
case SQLConstant.KW_AND:
|
||||
ret.retainAll(temp);
|
||||
break;
|
||||
case SQLConstant.KW_OR:
|
||||
ret.addAll(temp);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("given error token type:"+deltaFilterOperator.getTokenIntType());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfiledb.auth.model.AuthException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.author.AuthorOperator.AuthorType;
|
||||
|
||||
/**
|
||||
* given a author related plan and construct a {@code AuthorPlan}
|
||||
*
|
||||
* @author kangrong、whw
|
||||
*
|
||||
*/
|
||||
public class AuthorPlan extends PhysicalPlan {
|
||||
private final AuthorType authorType;
|
||||
private String userName;
|
||||
private String roleName;
|
||||
private String password;
|
||||
/*
|
||||
* 刘昆修改的添加new password
|
||||
*/
|
||||
private String newPassword;
|
||||
private String[] authorizationList;
|
||||
private Path nodeName;
|
||||
|
||||
public AuthorPlan(AuthorType authorType, String userName, String roleName, String password, String newPassword,
|
||||
String[] authorizationList, Path nodeName) {
|
||||
super(false, OperatorType.AUTHOR);
|
||||
this.authorType = authorType;
|
||||
this.userName = userName;
|
||||
this.roleName = roleName;
|
||||
this.password = password;
|
||||
this.newPassword = newPassword;
|
||||
this.authorizationList = authorizationList;
|
||||
this.nodeName = nodeName;
|
||||
}
|
||||
|
||||
public boolean processNonQuery(QueryProcessExecutor config) throws ProcessorException{
|
||||
try {
|
||||
boolean flag = true;
|
||||
Set<Integer> permissions;
|
||||
switch (authorType) {
|
||||
/*
|
||||
* 刘昆修改添加一个物理修改密码的操作
|
||||
*
|
||||
*/
|
||||
case UPDATE_USER:
|
||||
return config.updateUser(userName, newPassword);
|
||||
case CREATE_USER:
|
||||
return config.createUser(userName, password);
|
||||
case CREATE_ROLE:
|
||||
return config.createRole(roleName);
|
||||
case DROP_USER:
|
||||
return config.deleteUser(userName);
|
||||
case DROP_ROLE:
|
||||
return config.deleteRole(roleName);
|
||||
case GRANT_ROLE:
|
||||
permissions = pmsToInt(authorizationList);
|
||||
for (int i : permissions) {
|
||||
if (!config.addPmsToRole(roleName, nodeName.getFullPath(), i))
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
case GRANT_USER:
|
||||
permissions = pmsToInt(authorizationList);
|
||||
for (int i : permissions) {
|
||||
if (!config.addPmsToUser(userName, nodeName.getFullPath(), i))
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
case GRANT_ROLE_TO_USER:
|
||||
return config.grantRoleToUser(roleName, userName);
|
||||
case REVOKE_USER:
|
||||
permissions = pmsToInt(authorizationList);
|
||||
for (int i : permissions) {
|
||||
if (!config.removePmsFromUser(userName, nodeName.getFullPath(), i))
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
case REVOKE_ROLE:
|
||||
permissions = pmsToInt(authorizationList);
|
||||
for (int i : permissions) {
|
||||
if (!config.removePmsFromRole(roleName, nodeName.getFullPath(), i))
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
case REVOKE_ROLE_FROM_USER:
|
||||
return config.revokeRoleFromUser(roleName, userName);
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (AuthException e) {
|
||||
throw new ProcessorException(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Integer> pmsToInt(String[] authorizationList) {
|
||||
Set<Integer> result = new HashSet<Integer>();
|
||||
for (String s : authorizationList) {
|
||||
s = s.toUpperCase();
|
||||
switch (s) {
|
||||
case "CREATE":
|
||||
result.add(0);
|
||||
break;
|
||||
case "INSERT":
|
||||
result.add(1);
|
||||
break;
|
||||
case "MODIFY":
|
||||
result.add(2);
|
||||
break;
|
||||
case "READ":
|
||||
result.add(3);
|
||||
break;
|
||||
case "DELETE":
|
||||
result.add(4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (nodeName != null)
|
||||
ret.add(nodeName);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
|
||||
/**
|
||||
* given a delete plan and construct a {@code DeletePlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class DeletePlan extends PhysicalPlan {
|
||||
private long deleteTime;
|
||||
private Path path;
|
||||
|
||||
public DeletePlan() {
|
||||
super(false, OperatorType.DELETE);
|
||||
}
|
||||
|
||||
public DeletePlan(long deleteTime, Path path) {
|
||||
super(false, OperatorType.DELETE);
|
||||
this.setDeleteTime(deleteTime);
|
||||
this.setPath(path);
|
||||
}
|
||||
@Override
|
||||
public boolean processNonQuery(QueryProcessExecutor exec) throws ProcessorException {
|
||||
return exec.delete(path, deleteTime);
|
||||
}
|
||||
|
||||
public long getDeleteTime() {
|
||||
return deleteTime;
|
||||
}
|
||||
|
||||
public void setDeleteTime(long delTime) {
|
||||
this.deleteTime = delTime;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (path != null)
|
||||
ret.add(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
|
||||
/**
|
||||
* given a insert plan and construct a {@code InsertPlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class InsertPlan extends PhysicalPlan {
|
||||
private long insertTime;
|
||||
private String value;
|
||||
private Path path;
|
||||
//insertType : 1表示插入到Bufferwrite,2表示插入到Overflow
|
||||
private int insertType;
|
||||
|
||||
public InsertPlan() {
|
||||
super(false, OperatorType.INSERT);
|
||||
}
|
||||
|
||||
public InsertPlan(int insertType, long insertTime, String value, Path path) {
|
||||
super(false, OperatorType.INSERT);
|
||||
this.insertType = insertType;
|
||||
this.insertTime = insertTime;
|
||||
this.value = value;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processNonQuery(QueryProcessExecutor exec) throws ProcessorException{
|
||||
insertType = exec.insert(path, insertTime, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return insertTime;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.insertTime = time;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (path != null)
|
||||
ret.add(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getInsertType() {
|
||||
return insertType;
|
||||
}
|
||||
|
||||
public void setInsertType(int insertType) {
|
||||
this.insertType = insertType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.utils.LoadDataUtils;
|
||||
|
||||
/**
|
||||
* given a author related plan and construct a {@code AuthorPlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class LoadDataPlan extends PhysicalPlan {
|
||||
private final String inputFilePath;
|
||||
private final String measureType;
|
||||
|
||||
public LoadDataPlan(String inputFilePath, String measureType) {
|
||||
super(false, OperatorType.LOADDATA);
|
||||
this.inputFilePath = inputFilePath;
|
||||
this.measureType = measureType;
|
||||
}
|
||||
|
||||
public boolean processNonQuery(QueryProcessExecutor config) {
|
||||
LoadDataUtils load = new LoadDataUtils();
|
||||
load.loadLocalDataMultiPass(inputFilePath, measureType, config.getMManager());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (measureType != null)
|
||||
ret.add(new Path(measureType));
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
|
||||
/**
|
||||
* given a insert plan and construct a {@code InsertPlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MultiInsertPlan extends PhysicalPlan {
|
||||
private String deltaObject;
|
||||
private List<String> measurementList;
|
||||
private List<String> insertValues;
|
||||
private long insertTime;
|
||||
|
||||
|
||||
//insertType : 1表示插入到Bufferwrite,2表示插入到Overflow
|
||||
private int insertType;
|
||||
|
||||
public MultiInsertPlan() {
|
||||
super(false, OperatorType.MULTIINSERT);
|
||||
}
|
||||
|
||||
public MultiInsertPlan(String deltaObject, long insertTime, List<String> measurementList, List<String> insertValues) {
|
||||
super(false, OperatorType.MULTIINSERT);
|
||||
this.insertTime = insertTime;
|
||||
this.deltaObject = deltaObject;
|
||||
this.measurementList = measurementList;
|
||||
this.insertValues = insertValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processNonQuery(QueryProcessExecutor exec) throws ProcessorException{
|
||||
insertType = exec.multiInsert(deltaObject, insertTime, measurementList, insertValues);
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return insertTime;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.insertTime = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<>();
|
||||
|
||||
for(String m : measurementList){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(deltaObject);
|
||||
sb.append(".");
|
||||
sb.append(m);
|
||||
Path p = new Path(sb.toString());
|
||||
ret.add(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getInsertType() {
|
||||
return insertType;
|
||||
}
|
||||
|
||||
public void setInsertType(int insertType) {
|
||||
this.insertType = insertType;
|
||||
}
|
||||
|
||||
public String getDeltaObject() {
|
||||
return this.deltaObject;
|
||||
}
|
||||
|
||||
public void setDeltaObject(String deltaObject) {
|
||||
this.deltaObject = deltaObject;
|
||||
}
|
||||
|
||||
public List<String> getMeasurementList() {
|
||||
return this.measurementList;
|
||||
}
|
||||
|
||||
public void setMeasurementList(List<String> measurementList) {
|
||||
this.measurementList = measurementList;
|
||||
}
|
||||
|
||||
public List<String> getInsertValues() {
|
||||
return this.insertValues;
|
||||
}
|
||||
|
||||
public void setInsertValues(List<String> insertValues) {
|
||||
this.insertValues = insertValues;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.physical.plan.PhysicalPlanException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
|
||||
/**
|
||||
* This class is a abstract class for all type of PhysicalPlan. PhysicalPlan is a binary tree and is
|
||||
* processed along preorder traversal.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public abstract class PhysicalPlan {
|
||||
private boolean isQuery;
|
||||
private OperatorType operatorType;
|
||||
|
||||
protected PhysicalPlan(boolean isQuery, OperatorType operatorType) {
|
||||
this.isQuery = isQuery;
|
||||
this.operatorType = operatorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* input a getIndex processing config and process the getIndex
|
||||
*
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
public Iterator<QueryDataSet> processQuery(QueryProcessExecutor config) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* input a getIndex processing config and process insert/update/delete
|
||||
*
|
||||
* @param config
|
||||
* @return
|
||||
* @throws PhysicalPlanException
|
||||
*/
|
||||
public boolean processNonQuery(QueryProcessExecutor config) throws ProcessorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String printQueryPlan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public abstract List<Path> getInvolvedSeriesPaths();
|
||||
|
||||
public boolean isQuery(){
|
||||
return isQuery;
|
||||
}
|
||||
|
||||
public OperatorType getOperatorType() {
|
||||
return operatorType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
|
||||
|
||||
/**
|
||||
* given a update plan and construct a {@code UpdatePlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class UpdatePlan extends PhysicalPlan {
|
||||
private long startTime;
|
||||
private long endTime;
|
||||
private String value;
|
||||
private Path path;
|
||||
|
||||
public UpdatePlan() {
|
||||
super(false, OperatorType.UPDATE);
|
||||
}
|
||||
|
||||
public UpdatePlan(long startTime, long endTime, String value, Path path) {
|
||||
super(false, OperatorType.UPDATE);
|
||||
this.setStartTime(startTime);
|
||||
this.setEndTime(endTime);
|
||||
this.setValue(value);
|
||||
this.setPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processNonQuery(QueryProcessExecutor exec) throws ProcessorException {
|
||||
return exec.update(path, startTime, endTime, value);
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(long endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (path != null)
|
||||
ret.add(path);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.metadata;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfiledb.exception.ArgsErrorException;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.physical.plan.NamespacePlanException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.physical.plan.PhysicalPlanException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.metadata.MetadataOperator.NamespaceType;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.DeletePlan;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* given a author related plan and construct a {@code AuthorPlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MetadataPlan extends PhysicalPlan {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MetadataPlan.class);
|
||||
private final NamespaceType namespaceType;
|
||||
private Path path;
|
||||
private String dataType;
|
||||
private String encoding;
|
||||
private String[] encodingArgs;
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setDataType(String dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public String[] getEncodingArgs() {
|
||||
return encodingArgs;
|
||||
}
|
||||
|
||||
public void setEncodingArgs(String[] encodingArgs) {
|
||||
this.encodingArgs = encodingArgs;
|
||||
}
|
||||
|
||||
public NamespaceType getNamespaceType() {
|
||||
return namespaceType;
|
||||
}
|
||||
|
||||
public MetadataPlan(NamespaceType namespaceType, Path path, String dataType, String encoding,
|
||||
String[] encodingArgs) {
|
||||
super(false, OperatorType.METADATA);
|
||||
this.namespaceType = namespaceType;
|
||||
this.path = path;
|
||||
this.dataType = dataType;
|
||||
this.encoding = encoding;
|
||||
this.encodingArgs = encodingArgs;
|
||||
}
|
||||
|
||||
public boolean processNonQuery(QueryProcessExecutor config) throws ProcessorException {
|
||||
MManager mManager = config.getMManager();
|
||||
try {
|
||||
switch (namespaceType) {
|
||||
case ADD_PATH:
|
||||
mManager.addAPathToMTree(path.getFullPath(), dataType, encoding, encodingArgs);
|
||||
break;
|
||||
case DELETE_PATH:
|
||||
try {
|
||||
// First delete all data interactive
|
||||
deleteAllData(config);
|
||||
// Then delete the metadata
|
||||
mManager.deletePathFromMTree(path.getFullPath());
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SET_FILE_LEVEL:
|
||||
mManager.setStorageLevelToMTree(path.getFullPath());
|
||||
break;
|
||||
default:
|
||||
throw new ProcessorException("unkown namespace type:" + namespaceType);
|
||||
}
|
||||
} catch (PathErrorException | IOException | ArgsErrorException e) {
|
||||
throw new ProcessorException("meet err in " + namespaceType + " . " + e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteAllData(QueryProcessExecutor config) throws PathErrorException, ProcessorException {
|
||||
MManager mManager = config.getMManager();
|
||||
ArrayList<String> pathList = mManager.getPaths(path.getFullPath());
|
||||
for (String p : pathList) {
|
||||
if(mManager.pathExist(p)){
|
||||
DeletePlan deletePlan = new DeletePlan();
|
||||
deletePlan.setPath(new Path(p));
|
||||
deletePlan.setDeleteTime(Long.MAX_VALUE);
|
||||
deletePlan.processNonQuery(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (path != null)
|
||||
ret.add(path);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.metadata;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfiledb.exception.ArgsErrorException;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.physical.plan.NamespacePlanException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.physical.plan.PhysicalPlanException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.metadata.PropertyOperator.PropertyType;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* given a author related plan and construct a {@code AuthorPlan}
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class PropertyPlan extends PhysicalPlan {
|
||||
private final PropertyType propertyType;
|
||||
private Path propertyPath;
|
||||
private Path metadataPath;
|
||||
|
||||
public Path getPropertyPath() {
|
||||
return propertyPath;
|
||||
}
|
||||
|
||||
public void setPropertyPath(Path propertyPath) {
|
||||
this.propertyPath = propertyPath;
|
||||
}
|
||||
|
||||
public Path getMetadataPath() {
|
||||
return metadataPath;
|
||||
}
|
||||
|
||||
public void setMetadataPath(Path metadataPath) {
|
||||
this.metadataPath = metadataPath;
|
||||
}
|
||||
|
||||
public PropertyType getPropertyType() {
|
||||
return propertyType;
|
||||
}
|
||||
|
||||
|
||||
public PropertyPlan(PropertyType propertyType, Path propertyPath, Path metadataPath) {
|
||||
super(false, OperatorType.PROPERTY);
|
||||
this.propertyType = propertyType;
|
||||
this.propertyPath = propertyPath;
|
||||
this.metadataPath = metadataPath;
|
||||
}
|
||||
|
||||
public boolean processNonQuery(QueryProcessExecutor config) throws ProcessorException {
|
||||
MManager mManager = config.getMManager();
|
||||
try {
|
||||
switch (propertyType) {
|
||||
case ADD_TREE:
|
||||
mManager.addAPTree(propertyPath.getFullPath());
|
||||
break;
|
||||
case ADD_PROPERTY_LABEL:
|
||||
mManager.addAPathToPTree(propertyPath.getFullPath());
|
||||
break;
|
||||
case DELETE_PROPERTY_LABEL:
|
||||
mManager.deletePathFromPTree(propertyPath.getFullPath());
|
||||
break;
|
||||
case ADD_PROPERTY_TO_METADATA:
|
||||
mManager.linkMNodeToPTree(propertyPath.getFullPath(), metadataPath.getFullPath());
|
||||
break;
|
||||
case DEL_PROPERTY_FROM_METADATA:
|
||||
mManager.unlinkMNodeFromPTree(propertyPath.getFullPath(), metadataPath.getFullPath());
|
||||
break;
|
||||
default:
|
||||
throw new ProcessorException("unkown namespace type:" + propertyType);
|
||||
}
|
||||
} catch (PathErrorException | IOException | ArgsErrorException e) {
|
||||
throw new ProcessorException("meet err in " + propertyType +" . "+ e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
List<Path> ret = new ArrayList<Path>();
|
||||
if (metadataPath != null)
|
||||
ret.add(metadataPath);
|
||||
if (propertyPath != null)
|
||||
ret.add(propertyPath);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.query;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfile.timeseries.read.readSupport.RowRecord;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
|
||||
/**
|
||||
* This class implements the interface {@code Iterator<QueryDataSet>}. It is the result of
|
||||
* {@code MergeQuerySetPlan}(for multi-pass getIndex). {@code MergeQuerySetPlan} provides it with a
|
||||
* list of {@code SeriesSelectPlan}.<br>
|
||||
* This class merge row record data set from a list of {@code Iterator<RowRecord>} provided by
|
||||
* {@code SeriesSelectPlan} according to the time ascending, using <em>minimum heap</em>
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MergeQuerySetIterator implements Iterator<QueryDataSet> {
|
||||
private final int mergeFetchSize;
|
||||
// private RowRecord[] records;
|
||||
private Iterator<RowRecord>[] recordIters;
|
||||
private Node[] records;
|
||||
// it's actually number of series iterators which has next record;
|
||||
private int heapSize;
|
||||
private long lastRowTime = -1;
|
||||
|
||||
public MergeQuerySetIterator(List<SeriesSelectPlan> selectPlans, int mergeFetchSize,
|
||||
QueryProcessExecutor conf) {
|
||||
this.mergeFetchSize = mergeFetchSize;
|
||||
heapSize = selectPlans.size();
|
||||
records = new Node[heapSize + 1];
|
||||
recordIters = SeriesSelectPlan.getRecordIteratorArray(selectPlans, conf);
|
||||
initIters();
|
||||
}
|
||||
|
||||
private void initIters() {
|
||||
int index = 1;
|
||||
int tempSize = heapSize;
|
||||
for (int i = 0; i < tempSize; i++) {
|
||||
if (!recordIters[i].hasNext()) {
|
||||
heapSize--;
|
||||
} else {
|
||||
// add first value in all iterators to build minimum heap.
|
||||
records[index++] = new Node(recordIters[i].next(), recordIters[i]);
|
||||
}
|
||||
}
|
||||
// build minimum Heap
|
||||
for (int i = heapSize / 2; i >= 1; i--)
|
||||
minHeapify(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return heapSize > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryDataSet next() {
|
||||
QueryDataSet ret = new QueryDataSet();
|
||||
int i = 0;
|
||||
while (i < mergeFetchSize && heapSize > 0) {
|
||||
Node minNode = records[1];
|
||||
if (minNode.r.timestamp != lastRowTime) {
|
||||
lastRowTime = minNode.r.timestamp;
|
||||
i++;
|
||||
ret.putARowRecord(minNode.r);
|
||||
}
|
||||
if (minNode.iter.hasNext()) {
|
||||
records[1].r = records[1].iter.next();
|
||||
} else {
|
||||
records[1] = records[heapSize];
|
||||
heapSize -= 1;
|
||||
}
|
||||
minHeapify(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void minHeapify(int i) {
|
||||
int left = 2 * i;
|
||||
int right = 2 * i + 1;
|
||||
int min = i;
|
||||
|
||||
if (left <= heapSize && records[left].lessThan(records[i]))
|
||||
min = left;
|
||||
if (right <= heapSize && records[right].lessThan(records[min]))
|
||||
min = right;
|
||||
|
||||
if (min != i) {
|
||||
Node tmp = records[i];
|
||||
records[i] = records[min];
|
||||
records[min] = tmp;
|
||||
minHeapify(min);
|
||||
}
|
||||
}
|
||||
|
||||
private class Node {
|
||||
public RowRecord r;
|
||||
public Iterator<RowRecord> iter;
|
||||
|
||||
public Node(RowRecord r, Iterator<RowRecord> iter) {
|
||||
this.r = r;
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
public boolean lessThan(Node o) {
|
||||
if (r == null || o.r == null)
|
||||
System.err.println("asdasdas");
|
||||
return r.timestamp < o.r.timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return r.toString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* {@code MergeQuerySetPlan} is used in multi-pass getIndex plan. Multi-pass means it's a disjunction
|
||||
* among a list of single getIndex. {@code MergeQuerySetPlan} return a {@code Iterator<QueryDataSet>}
|
||||
* provided by {@code SeriesSelectPlan} for one-pass getIndex, or a {@code MergeQuerySetIterator} for
|
||||
* multi-pass getIndex.
|
||||
*
|
||||
* @see cn.edu.thu.tsfiledb.qp.physical.plan.query.SeriesSelectPlan
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class MergeQuerySetPlan extends PhysicalPlan {
|
||||
private static Logger LOG = LoggerFactory.getLogger(MergeQuerySetPlan.class);
|
||||
protected List<SeriesSelectPlan> selectPlans;
|
||||
|
||||
public List<SeriesSelectPlan> getSelectPlans() {
|
||||
return selectPlans;
|
||||
}
|
||||
|
||||
public MergeQuerySetPlan(ArrayList<SeriesSelectPlan> selectPlans) {
|
||||
super(true, OperatorType.QUERY);
|
||||
if (selectPlans == null || selectPlans.isEmpty()) {
|
||||
LOG.error("cannot input an null or empty plan list into QuerySetMergePlan! ");
|
||||
}
|
||||
this.selectPlans = selectPlans;
|
||||
}
|
||||
|
||||
public void setSelectPlans(List<SeriesSelectPlan> selectPlans) {
|
||||
this.selectPlans = selectPlans;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<QueryDataSet> processQuery(QueryProcessExecutor conf) {
|
||||
if (selectPlans.size() == 1)
|
||||
// return new SingleQuerySetIterator(conf, selectPlans[0]);
|
||||
return selectPlans.get(0).processQuery(conf);
|
||||
else
|
||||
return new MergeQuerySetIterator(selectPlans, conf.getFetchSize(), conf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String printQueryPlan() {
|
||||
// LOG.info("show getIndex plan:");
|
||||
StringContainer sc = new StringContainer("\n");
|
||||
for (int i = 0; i < selectPlans.size(); i++) {
|
||||
sc.addTail("showing series plan:" + i);
|
||||
sc.addTail(selectPlans.get(i).printQueryPlan());
|
||||
}
|
||||
return sc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
if(selectPlans == null || selectPlans.size() == 0)
|
||||
return new ArrayList<Path>();
|
||||
else{
|
||||
List<Path> ret = new ArrayList<>();
|
||||
LinkedHashMap<Path,Integer> pathMap = new LinkedHashMap<>();
|
||||
for (SeriesSelectPlan series : selectPlans) {
|
||||
for(Path p : series.getInvolvedSeriesPaths()){
|
||||
if(!pathMap.containsKey(p)){
|
||||
pathMap.put(p, 1);
|
||||
ret.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.query;
|
||||
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfile.timeseries.read.readSupport.RowRecord;
|
||||
|
||||
/**
|
||||
* This class extends {@link cn.edu.thu.tsfiledb.read.query.QueryDataSet}.<br>
|
||||
* This getIndex data set is used for getIndex processing. getIndex processing merges a list of QueryDataSet
|
||||
* and construct a new OutputQueryDataSet by adding {@code RowRecord}. This class provides two
|
||||
* methods for caller {@code getNextRecord} and {@code hasNextRecord} just same as
|
||||
* {@code QueryDataSet}.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class OutputQueryDataSet extends QueryDataSet {
|
||||
protected final int fetchSize;
|
||||
protected RowRecord[] data;
|
||||
protected int size;
|
||||
protected int index;
|
||||
|
||||
public OutputQueryDataSet(int fetchSize) {
|
||||
this.fetchSize = fetchSize;
|
||||
data = new RowRecord[fetchSize];
|
||||
size = 0;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* put a rowRecord into this DataSet.
|
||||
*
|
||||
* @param r - rowRecord to be added.
|
||||
* @return if amount of exist record equals to fetchSize, return false, otherwise return true.
|
||||
*
|
||||
*/
|
||||
public boolean addRowRecord(RowRecord r) {
|
||||
if (size < fetchSize) {
|
||||
data[size++] = r;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For efficiency, this method don't check index boundary. caller should check index boundary by
|
||||
* {@code hasNextRecord} before calling this method.
|
||||
*/
|
||||
@Override
|
||||
public RowRecord getNextRecord() {
|
||||
return data[index++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextRecord() {
|
||||
return index < size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,341 @@
|
|||
package cn.edu.thu.tsfiledb.qp.physical.plan.query;
|
||||
|
||||
import static cn.edu.thu.tsfiledb.qp.constant.SQLConstant.lineFeedSignal;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.FilterFactory;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.SingleSeriesFilterExpression;
|
||||
import cn.edu.thu.tsfile.timeseries.filter.definition.filterseries.FilterSeries;
|
||||
import cn.edu.thu.tsfile.timeseries.read.query.QueryDataSet;
|
||||
import cn.edu.thu.tsfile.timeseries.read.readSupport.RowRecord;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.StringContainer;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.qp.exception.QueryProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.read.qp.Path;
|
||||
import cn.edu.thu.tsfiledb.qp.exec.QueryProcessExecutor;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.Operator.OperatorType;
|
||||
import cn.edu.thu.tsfiledb.qp.logical.operator.crud.FilterOperator;
|
||||
import cn.edu.thu.tsfiledb.qp.physical.plan.PhysicalPlan;
|
||||
|
||||
/**
|
||||
* This class is constructed with a single getIndex plan. Single getIndex means it could be processed by
|
||||
* reading API by one pass directly.<br>
|
||||
* Up to now, Single Query what {@code reading API} supports means it's a conjunction among time
|
||||
* filter, frequency filter and value filter. <br>
|
||||
* This class provide two public function. If the whole getIndex plan has exactly one single getIndex,
|
||||
* {@code SeriesSelectPlan} return a {@code Iterator<QueryDataSet>} directly. Otherwise
|
||||
* {@code SeriesSelectPlan} is regard as a portion of {@code MergeQuerySetPlan}. This class provide
|
||||
* a {@code Iterator<RowRecord>}in the latter case.
|
||||
*
|
||||
* @author kangrong
|
||||
*
|
||||
*/
|
||||
public class SeriesSelectPlan extends PhysicalPlan {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SeriesSelectPlan.class);
|
||||
private List<Path> paths;
|
||||
private FilterOperator deltaObjectFilterOperator;
|
||||
|
||||
public FilterOperator getDeltaObjectFilterOperator() {
|
||||
return deltaObjectFilterOperator;
|
||||
}
|
||||
|
||||
public void setDeltaObjectFilterOperator(FilterOperator deltaObjectFilterOperator) {
|
||||
this.deltaObjectFilterOperator = deltaObjectFilterOperator;
|
||||
}
|
||||
|
||||
private FilterOperator timeFilterOperator;
|
||||
private FilterOperator freqFilterOperator;
|
||||
private FilterOperator valueFilterOperator;
|
||||
|
||||
public List<Path> getPaths() {
|
||||
return paths;
|
||||
}
|
||||
|
||||
public FilterOperator getTimeFilterOperator() {
|
||||
return timeFilterOperator;
|
||||
}
|
||||
|
||||
public FilterOperator getFreqFilterOperator() {
|
||||
return freqFilterOperator;
|
||||
}
|
||||
|
||||
public FilterOperator getValueFilterOperator() {
|
||||
return valueFilterOperator;
|
||||
}
|
||||
|
||||
public SeriesSelectPlan(List<Path> paths, FilterOperator timeFilter, FilterOperator freqFilter,
|
||||
FilterOperator valueFilter, QueryProcessExecutor conf) {
|
||||
this(paths, null, timeFilter, freqFilter, valueFilter, conf);
|
||||
}
|
||||
|
||||
public SeriesSelectPlan(List<Path> paths, FilterOperator deltaObjectFilterOperator,
|
||||
FilterOperator timeFilter, FilterOperator freqFilter, FilterOperator valueFilter, QueryProcessExecutor conf) {
|
||||
super(true, OperatorType.QUERY);
|
||||
this.paths = paths;
|
||||
this.deltaObjectFilterOperator = deltaObjectFilterOperator;
|
||||
this.timeFilterOperator = timeFilter;
|
||||
this.freqFilterOperator = freqFilter;
|
||||
this.valueFilterOperator = valueFilter;
|
||||
removeStarsInPath(conf);
|
||||
LOG.info(Arrays.toString(paths.toArray()));
|
||||
removeNotExistsPaths(conf);
|
||||
LOG.info(Arrays.toString(paths.toArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<QueryDataSet> processQuery(QueryProcessExecutor conf) {
|
||||
FilterExpression[] exprs;
|
||||
try {
|
||||
exprs = transformFilterOpToExpression(conf);
|
||||
} catch (QueryProcessorException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return new QueryDataSetIterator(paths, conf.getFetchSize(), conf, exprs[0], exprs[1],
|
||||
exprs[2]);
|
||||
}
|
||||
|
||||
private void removeStarsInPath(QueryProcessExecutor conf) {
|
||||
LinkedHashMap<String, Integer> pathMap = new LinkedHashMap<>();
|
||||
for (Path path : paths) {
|
||||
List<String> all = null;
|
||||
try {
|
||||
all = conf.getAllPaths(path.getFullPath());
|
||||
for(String subp : all){
|
||||
if(!pathMap.containsKey(subp)){
|
||||
pathMap.put(subp, 1);
|
||||
}
|
||||
}
|
||||
} catch (PathErrorException e) {
|
||||
LOG.error("path error:" + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
paths = new ArrayList<Path>();
|
||||
for (String pathStr : pathMap.keySet()) {
|
||||
paths.add(new Path(pathStr));
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNotExistsPaths(QueryProcessExecutor conf) {
|
||||
List<Path> existsPaths = new ArrayList<Path>();
|
||||
List<Path> notExistsPaths = new ArrayList<Path>();
|
||||
for (Path path : paths) {
|
||||
if (conf.judgePathExists(path))
|
||||
existsPaths.add(path);
|
||||
else
|
||||
notExistsPaths.add(path);
|
||||
}
|
||||
if (!notExistsPaths.isEmpty()) {
|
||||
LOG.warn("following paths don't exist:{}", notExistsPaths.toString());
|
||||
}
|
||||
this.paths = existsPaths;
|
||||
|
||||
}
|
||||
|
||||
private FilterExpression[] transformFilterOpToExpression(QueryProcessExecutor conf)
|
||||
throws QueryProcessorException {
|
||||
FilterExpression timeFilter =
|
||||
timeFilterOperator == null ? null : timeFilterOperator.transformToFilter(conf);
|
||||
FilterExpression freqFilter =
|
||||
freqFilterOperator == null ? null : freqFilterOperator.transformToFilter(conf);
|
||||
FilterExpression valueFilter =
|
||||
valueFilterOperator == null ? null : valueFilterOperator.transformToFilter(conf);
|
||||
// TODO maybe it's a temporary solution. Up to now, if a crossSensorFilter is needed, just
|
||||
// construct it with two same children via CSAnd(valueFilter, valueFilter)
|
||||
if (valueFilter instanceof SingleSeriesFilterExpression) {
|
||||
if (paths.size() == 1) {
|
||||
FilterSeries<?> series = ((SingleSeriesFilterExpression) valueFilter).getFilterSeries();
|
||||
Path path = paths.get(0);
|
||||
if (!series.getDeltaObjectUID().equals(path.getDeltaObjectToString())
|
||||
|| !series.getMeasurementUID().equals(path.getMeasurementToString())) {
|
||||
valueFilter = FilterFactory.and(valueFilter, valueFilter);
|
||||
}
|
||||
} else
|
||||
valueFilter = FilterFactory.and(valueFilter, valueFilter);
|
||||
}
|
||||
return new FilterExpression[] {timeFilter, freqFilter, valueFilter};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* provide {@code Iterator<RowRecord>} for
|
||||
* {@link cn.edu.thu.tsfiledb.qp.physical.plan.query.MergeQuerySetIterator} which has more than one
|
||||
* {@code SeriesSelectPlan} to merge
|
||||
*
|
||||
* @param conf
|
||||
* @return
|
||||
*/
|
||||
private Iterator<RowRecord> getRecordIterator(QueryProcessExecutor conf) {
|
||||
FilterExpression[] exprs = null;
|
||||
try {
|
||||
exprs = transformFilterOpToExpression(conf);
|
||||
} catch (QueryProcessorException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return new RowRecordIterator(conf.getFetchSize(), conf, exprs[0], exprs[1], exprs[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* provide {@code Iterator<QueryDataSet>} for
|
||||
* {@link com.corp.tsfile.qp.physical.plan.MergeQuerySetIterator} which has exactly one
|
||||
* {@code SeriesSelectPlan}.
|
||||
*
|
||||
* @param conf
|
||||
* @return
|
||||
*/
|
||||
// public Iterator<QueryDataSet> getQueryDataSetIterator(QueryProcessExecutor conf) {
|
||||
// return new QueryDataSetIterator(conf.getFetchSize(), conf);
|
||||
// }
|
||||
|
||||
/**
|
||||
* only used by
|
||||
*
|
||||
* @param plans
|
||||
* @param conf
|
||||
* @return
|
||||
*/
|
||||
public static Iterator<RowRecord>[] getRecordIteratorArray(List<SeriesSelectPlan> plans,
|
||||
QueryProcessExecutor conf) {
|
||||
Iterator<RowRecord>[] ret = new RowRecordIterator[plans.size()];
|
||||
for (int i = 0; i < plans.size(); i++) {
|
||||
ret[i] = plans.get(i).getRecordIterator(conf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public class RowRecordIterator implements Iterator<RowRecord> {
|
||||
private boolean noNext = false;
|
||||
private final int fetchSize;
|
||||
private final QueryProcessExecutor conf;
|
||||
private QueryDataSet data = null;
|
||||
private FilterExpression timeFilter;
|
||||
private FilterExpression freqFilter;
|
||||
private FilterExpression valueFilter;
|
||||
|
||||
public RowRecordIterator(int fetchSize, QueryProcessExecutor conf,
|
||||
FilterExpression timeFilter, FilterExpression freqFilter,
|
||||
FilterExpression valueFilter) {
|
||||
this.fetchSize = fetchSize;
|
||||
this.conf = conf;
|
||||
this.timeFilter = timeFilter;
|
||||
this.freqFilter = freqFilter;
|
||||
this.valueFilter = valueFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext(){
|
||||
if (noNext)
|
||||
return false;
|
||||
if (data == null || !data.hasNextRecord())
|
||||
try {
|
||||
data = conf.query(paths, timeFilter, freqFilter, valueFilter, fetchSize, data);
|
||||
} catch (ProcessorException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
if (data.hasNextRecord())
|
||||
return true;
|
||||
else {
|
||||
noNext = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowRecord next() {
|
||||
return data.getNextRecord();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class QueryDataSetIterator implements Iterator<QueryDataSet> {
|
||||
private boolean noNext = false;
|
||||
private final int fetchSize;
|
||||
private final QueryProcessExecutor conf;
|
||||
private QueryDataSet data = null;
|
||||
private QueryDataSet usedData = null;
|
||||
private FilterExpression timeFilter;
|
||||
private FilterExpression freqFilter;
|
||||
private FilterExpression valueFilter;
|
||||
private List<Path> paths;
|
||||
|
||||
public QueryDataSetIterator(List<Path> paths, int fetchSize, QueryProcessExecutor conf,
|
||||
FilterExpression timeFilter, FilterExpression freqFilter,
|
||||
FilterExpression valueFilter) {
|
||||
this.paths = paths;
|
||||
this.fetchSize = fetchSize;
|
||||
this.conf = conf;
|
||||
this.timeFilter = timeFilter;
|
||||
this.freqFilter = freqFilter;
|
||||
this.valueFilter = valueFilter;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (usedData != null) {
|
||||
usedData.clear();
|
||||
}
|
||||
if (noNext)
|
||||
return false;
|
||||
if (data == null || !data.hasNextRecord())
|
||||
try {
|
||||
data = conf.query(paths, timeFilter, freqFilter, valueFilter, fetchSize, usedData);
|
||||
} catch (ProcessorException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
if (data == null) {
|
||||
LOG.error(
|
||||
"data is null! parameters: paths:{},timeFilter:{}, freqFilter:{}, valueFilter:{}, fetchSize:{}, usedData:{}",
|
||||
paths, timeFilter, freqFilter, valueFilter, fetchSize, usedData);
|
||||
throw new RuntimeException("data is null! parameters: paths:");
|
||||
}
|
||||
if (data.hasNextRecord())
|
||||
return true;
|
||||
else {
|
||||
noNext = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryDataSet next() {
|
||||
usedData = data;
|
||||
data = null;
|
||||
return usedData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String printQueryPlan() {
|
||||
StringContainer sc = new StringContainer();
|
||||
String preSpace = " ";
|
||||
sc.addTail(preSpace, "series getIndex plan:", lineFeedSignal);
|
||||
sc.addTail(preSpace, "paths: ").addTail(paths.toString(), lineFeedSignal);
|
||||
sc.addTail(preSpace, timeFilterOperator == null ? "null" : timeFilterOperator.toString(),
|
||||
lineFeedSignal);
|
||||
sc.addTail(preSpace, freqFilterOperator == null ? "null" : freqFilterOperator.toString(),
|
||||
lineFeedSignal);
|
||||
sc.addTail(preSpace, valueFilterOperator == null ? "null" : valueFilterOperator.toString(),
|
||||
lineFeedSignal);
|
||||
return sc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Path> getInvolvedSeriesPaths() {
|
||||
if (paths == null)
|
||||
return new ArrayList<Path>();
|
||||
else
|
||||
return paths;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package cn.edu.thu.tsfiledb.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import cn.edu.thu.tsfile.common.constant.JsonFormatConstant;
|
||||
import cn.edu.thu.tsfile.timeseries.write.exception.InvalidJsonSchemaException;
|
||||
import cn.edu.thu.tsfile.timeseries.write.schema.FileSchema;
|
||||
import cn.edu.thu.tsfiledb.metadata.ColumnSchema;
|
||||
|
||||
public class FileSchemaUtil {
|
||||
|
||||
public static FileSchema getFileSchemaFromColumnSchema(List<ColumnSchema> schemaList, String measureType) {
|
||||
JSONObject jsonSchema = new JSONObject();
|
||||
JSONArray rowGroupArray = new JSONArray();
|
||||
|
||||
for (ColumnSchema col : schemaList) {
|
||||
JSONObject s1 = new JSONObject();
|
||||
s1.put(JsonFormatConstant.MEASUREMENT_UID, col.name);
|
||||
s1.put(JsonFormatConstant.DATA_TYPE, col.dataType.toString());
|
||||
s1.put(JsonFormatConstant.MEASUREMENT_ENCODING, col.encoding.toString());
|
||||
for (Entry<String, String> entry : col.getArgsMap().entrySet()) {
|
||||
if (JsonFormatConstant.ENUM_VALUES.equals(entry.getKey())) {
|
||||
String[] valueArray = entry.getValue().split(",");
|
||||
s1.put(JsonFormatConstant.ENUM_VALUES, new JSONArray(valueArray));
|
||||
} else
|
||||
s1.put(entry.getKey(), entry.getValue().toString());
|
||||
}
|
||||
rowGroupArray.put(s1);
|
||||
}
|
||||
|
||||
jsonSchema.put(JsonFormatConstant.DELTA_TYPE, measureType);
|
||||
jsonSchema.put(JsonFormatConstant.JSON_SCHEMA, rowGroupArray);
|
||||
FileSchema fileSchema = null;
|
||||
try {
|
||||
fileSchema = new FileSchema(jsonSchema);
|
||||
} catch (InvalidJsonSchemaException e) {
|
||||
//This exception won't occur
|
||||
e.printStackTrace();
|
||||
}
|
||||
return fileSchema;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
package cn.edu.thu.tsfiledb.utils;
|
||||
|
||||
import org.apache.derby.tools.sysinfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import cn.edu.thu.tsfile.common.conf.TSFileConfig;
|
||||
import cn.edu.thu.tsfile.common.conf.TSFileDescriptor;
|
||||
import cn.edu.thu.tsfile.common.exception.ProcessorException;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.FileUtils;
|
||||
import cn.edu.thu.tsfile.timeseries.utils.RecordUtils;
|
||||
import cn.edu.thu.tsfile.timeseries.write.record.TSRecord;
|
||||
import cn.edu.thu.tsfile.timeseries.write.schema.FileSchema;
|
||||
import cn.edu.thu.tsfiledb.engine.filenode.FileNodeManager;
|
||||
import cn.edu.thu.tsfiledb.exception.PathErrorException;
|
||||
import cn.edu.thu.tsfiledb.metadata.ColumnSchema;
|
||||
import cn.edu.thu.tsfiledb.metadata.MManager;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author kangrong
|
||||
*/
|
||||
public class LoadDataUtils {
|
||||
private static Logger LOG = LoggerFactory.getLogger(LoadDataUtils.class);
|
||||
private BufferedReader inputCsvFileReader;
|
||||
private BufferedWriter extraDataFileWriter;
|
||||
private FileSchema fileSchema;
|
||||
private Set<String> writeInstanceMap;
|
||||
private MManager mManager;
|
||||
private int writeInstanceThreshold;
|
||||
private boolean hasExtra = false;
|
||||
private String measureType;
|
||||
private long totalPointCount = 0;
|
||||
private FileNodeManager fileNodeManager;
|
||||
private TSFileConfig conf = TSFileDescriptor.getInstance().getConfig();
|
||||
|
||||
public LoadDataUtils() {
|
||||
writeInstanceMap = new HashSet<>();
|
||||
fileNodeManager = FileNodeManager.getInstance();
|
||||
writeInstanceThreshold = conf.writeInstanceThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inputCsvDataPath - path
|
||||
* @return - return extra data file in this circle as input csv path in next circle
|
||||
*/
|
||||
private String loadLocalDataOnePass(String inputCsvDataPath) {
|
||||
hasExtra = false;
|
||||
// prepare file for extra data
|
||||
String extraDataFilePath = prepareFilePathAddOne(inputCsvDataPath);
|
||||
File extraDataFile = new File(extraDataFilePath);
|
||||
try {
|
||||
this.extraDataFileWriter = new BufferedWriter(new FileWriter(extraDataFile));
|
||||
} catch (IOException e) {
|
||||
LOG.error("create");
|
||||
e.printStackTrace();
|
||||
close();
|
||||
return null;
|
||||
}
|
||||
// prepare input csv data file.
|
||||
try {
|
||||
this.inputCsvFileReader = new BufferedReader(new FileReader(inputCsvDataPath));
|
||||
} catch (FileNotFoundException e1) {
|
||||
LOG.error("inputCsvDataPath:{} not found!", inputCsvDataPath);
|
||||
close();
|
||||
return null;
|
||||
}
|
||||
// load data for each line
|
||||
long lineCount = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
long temp = System.currentTimeMillis();
|
||||
String line;
|
||||
try {
|
||||
while ((line = inputCsvFileReader.readLine()) != null) {
|
||||
if (lineCount % 1000000 == 0) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
LOG.info("write line:{}, use time:{}", lineCount,
|
||||
(endTime - temp));
|
||||
temp = System.currentTimeMillis();
|
||||
LOG.info("load data points:{}, load data speed:{}w point/s",
|
||||
totalPointCount, FileUtils.format(((float) totalPointCount / 10) / (endTime - startTime), 2));
|
||||
}
|
||||
loadOneRecordLine(line);
|
||||
lineCount++;
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
LOG.error("read line from inputCsvFileReader failed:{}", inputCsvDataPath);
|
||||
extraDataFilePath = null;
|
||||
} finally {
|
||||
LOG.info("write line:{}", lineCount);
|
||||
close();
|
||||
closeWriteInstance();
|
||||
}
|
||||
return extraDataFilePath;
|
||||
}
|
||||
|
||||
@SuppressWarnings("finally")
|
||||
private void loadOneRecordLine(String line) {
|
||||
TSRecord record = RecordUtils.parseSimpleTupleRecord(line, this.fileSchema);
|
||||
totalPointCount += record.dataPointList.size();
|
||||
String nsPath = null;
|
||||
try {
|
||||
nsPath = mManager.getFileNameByPath(record.deltaObjectId);
|
||||
} catch (PathErrorException e) {
|
||||
LOG.error("given path not found.{}", e.getMessage());
|
||||
}
|
||||
if (!writeInstanceMap.contains(nsPath)) {
|
||||
if (writeInstanceMap.size() < writeInstanceThreshold) {
|
||||
writeInstanceMap.add(nsPath);
|
||||
} else {
|
||||
hasExtra = true;
|
||||
try {
|
||||
extraDataFileWriter.write(line);
|
||||
extraDataFileWriter.newLine();
|
||||
} catch (IOException e) {
|
||||
LOG.error("record the extra data into extraFile failed, record:{}", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// appeared before, insert directly
|
||||
try {
|
||||
fileNodeManager.insert(record);
|
||||
} catch (ProcessorException e) {
|
||||
LOG.error("write record failed: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String prepareFilePathAddOne(String srcFilePath) {
|
||||
String extraExt = "deltaTempExt";
|
||||
int srcEnd = srcFilePath.indexOf(extraExt);
|
||||
if (srcEnd != -1)
|
||||
srcFilePath = srcFilePath.substring(0, srcEnd);
|
||||
File file;
|
||||
int ext = 0;
|
||||
String tempFile = srcFilePath;
|
||||
while (true) {
|
||||
file = new File(tempFile);
|
||||
if (file.exists())
|
||||
tempFile = srcFilePath + extraExt + (ext++);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
|
||||
private void close() {
|
||||
try {
|
||||
if (inputCsvFileReader != null)
|
||||
inputCsvFileReader.close();
|
||||
if (extraDataFileWriter != null)
|
||||
extraDataFileWriter.close();
|
||||
} catch (IOException e) {
|
||||
LOG.error("close inputCsvFileReader and extraDataFileWriter failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void closeWriteInstance() {
|
||||
//TODO for data load, don't close the write processor
|
||||
// for (Entry<String, WriteInstance> entry : writeInstanceMap.entrySet()) {
|
||||
// entry.getValue().close();
|
||||
// LOG.info("closed write instance:{}", entry.getKey());
|
||||
// }
|
||||
writeInstanceMap.clear();
|
||||
}
|
||||
|
||||
|
||||
public void loadLocalDataMultiPass(String inputCsvDataPath, String measureType,
|
||||
MManager mManager) {
|
||||
LOG.info("start loading data...");
|
||||
long start = System.currentTimeMillis();
|
||||
System.out.println("asdaasd");
|
||||
System.out.println("asdaasd");
|
||||
System.out.println("asdaasd");
|
||||
System.out.println("asdaasd");
|
||||
long startTime = System.currentTimeMillis();
|
||||
this.mManager = mManager;
|
||||
// get measurement schema
|
||||
try {
|
||||
ArrayList<ColumnSchema> meaSchema = mManager.getSchemaForOneType(measureType);
|
||||
this.measureType = measureType;
|
||||
fileSchema = FileSchemaUtil.getFileSchemaFromColumnSchema(meaSchema, measureType);
|
||||
} catch (PathErrorException e) {
|
||||
LOG.error("the path of input measurement schema meet error!");
|
||||
e.printStackTrace();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
String extraPath = inputCsvDataPath;
|
||||
List<String> extraPaths = new ArrayList<>();
|
||||
do {
|
||||
LOG.info("cycle: write csv file: {}", extraPath);
|
||||
extraPath = loadLocalDataOnePass(extraPath);
|
||||
extraPaths.add(extraPath);
|
||||
} while (hasExtra);
|
||||
for (String ext : extraPaths) {
|
||||
LOG.info("delete old file:{}", ext);
|
||||
new File(ext).delete();
|
||||
}
|
||||
long endTime = System.currentTimeMillis();
|
||||
LOG.info("load data successfully! total data points:{}, load data speed:{}w point/s",
|
||||
totalPointCount, FileUtils.format(((float) totalPointCount / 10) / (endTime - startTime), 2));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue