This commit is contained in:
xingtanzjr 2017-05-10 18:14:40 +08:00
parent 22a454e424
commit 2357155022
96 changed files with 7071 additions and 19 deletions

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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')";
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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();
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);

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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+"]";
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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));
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 kangrongwhw
*
*/
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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}