diff options
Diffstat (limited to 'juick-server-jdbc/src/main/java/com/juick')
16 files changed, 0 insertions, 3515 deletions
diff --git a/juick-server-jdbc/src/main/java/com/juick/configuration/UpdaterConfiguration.java b/juick-server-jdbc/src/main/java/com/juick/configuration/UpdaterConfiguration.java deleted file mode 100644 index 979b38f92..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/configuration/UpdaterConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.configuration; - -import com.juick.database.MySqlUpdater; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.transaction.PlatformTransactionManager; - -import javax.inject.Inject; - -/** - * Created by aalexeev on 12/13/16. - */ -@Configuration -public class UpdaterConfiguration { - @Inject - JdbcTemplate jdbcTemplate; - @Inject - PlatformTransactionManager transactionManager; - - @Bean - @DependsOn({"jdbcTemplate", "transactionManager"}) - public MySqlUpdater updater() { - return new MySqlUpdater( - jdbcTemplate, - transactionManager, - "update.sql"); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/database/MySqlUpdater.java b/juick-server-jdbc/src/main/java/com/juick/database/MySqlUpdater.java deleted file mode 100644 index 69cde40b8..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/database/MySqlUpdater.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.database; - -import org.apache.commons.codec.CharEncoding; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.util.Assert; - -import javax.annotation.PostConstruct; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRED; - -/** - * Created by aalexeev on 12/13/16. - */ -public class MySqlUpdater { - private static final Pattern UPDATE_PATTERN = Pattern.compile( - "update\\s+(version|`version`)\\s+set\\s+(version|`version`)\\s+=\\s*(\\d+)", - Pattern.CASE_INSENSITIVE); - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final JdbcTemplate jdbcTemplate; - private final TransactionTemplate transactionTemplate; - private final String updateSqlResource; - - - public MySqlUpdater(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager, String updateSqlResource) { - Assert.notNull(jdbcTemplate, "JdbcTemplate must be initialized"); - Assert.notNull(transactionManager, "PlatformTransactionManager must be initialized"); - Assert.notNull(updateSqlResource, "sqlResource must be initialized"); - - this.jdbcTemplate = jdbcTemplate; - this.transactionTemplate = new TransactionTemplate(transactionManager); - this.updateSqlResource = updateSqlResource; - } - - @PostConstruct - public void init() { - try ( - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(updateSqlResource); - ) { - if (is != null) { - String content = IOUtils.toString(is, CharEncoding.UTF_8); - if (StringUtils.isNotEmpty(content)) { - String[] sqlArray = content.split(";"); - if (sqlArray.length > 0) { - List<String> sqlList = new ArrayList<>(sqlArray.length); - for (String sql : sqlArray) - if (!sql.isEmpty()) { - String sqlTrimmed = sql.trim(); - if (!sqlTrimmed.isEmpty()) - sqlList.add(sqlTrimmed); - } - if (!sqlList.isEmpty()) - processingSql(sqlList); - } - } - } - } catch (Exception e) { - logger.error("MySqlUpdater initialization exception", e); - } - } - - private void processingSql(final List<String> sqls) { - long currentDbVersion = getSingleResult(this::getVersionRaw); - long actualVersion; - - List<String> changesSql = new ArrayList<>(); - - for (String sql : sqls) { - changesSql.add(sql); - - Matcher m = UPDATE_PATTERN.matcher(sql); - if (m.matches()) { - actualVersion = Long.valueOf(m.group(3)); - - if (actualVersion > currentDbVersion) { - updateInTransaction(changesSql); - currentDbVersion = actualVersion; - } - changesSql.clear(); - } - } - } - - private void updateInTransaction(final List<String> sqls) { - transactionTemplate.setReadOnly(false); - transactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRED); - transactionTemplate.execute(status -> { - for (String sql : sqls) - jdbcTemplate.execute(sql); - return 0; - }); - } - - private <T> T getSingleResult(Supplier<T> supplier) { - transactionTemplate.setReadOnly(true); - transactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRED); - - return transactionTemplate.execute(status -> supplier.get()); - } - - private long getVersionRaw() { - int cnt = jdbcTemplate.query( - "SELECT count(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?", - rs -> { - int result = 0; - if (rs.next()) - result = rs.getInt(1); - return result; - }, - "juick", "version"); - - long version = 0l; - - if (cnt == 1) { - List<Long> list = jdbcTemplate.queryForList("select version from version", Long.class); - if (!list.isEmpty()) - version = list.get(0); - } - - return version; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/BaseJdbcService.java b/juick-server-jdbc/src/main/java/com/juick/service/BaseJdbcService.java deleted file mode 100644 index 496a04ba6..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/BaseJdbcService.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; - -import javax.inject.Inject; - -/** - * Created by aalexeev on 11/13/16. - */ -public class BaseJdbcService { - @Inject - JdbcTemplate jdbcTemplate; - @Inject - NamedParameterJdbcTemplate namedParameterJdbcTemplate; - - public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { - return namedParameterJdbcTemplate; - } - - public JdbcTemplate getJdbcTemplate() { - return jdbcTemplate; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/CrosspostServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/CrosspostServiceImpl.java deleted file mode 100644 index 0bd5fe664..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/CrosspostServiceImpl.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.ExternalToken; -import com.juick.server.helpers.ApplicationStatus; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class CrosspostServiceImpl extends BaseJdbcService implements CrosspostService { - - @Transactional(readOnly = true) - @Override - public Optional<ExternalToken> getTwitterToken(final int uid) { - List<ExternalToken> list = getJdbcTemplate().query( - "SELECT uname, access_token, access_token_secret FROM twitter WHERE user_id = ? AND crosspost = 1", - (rs, num) -> new ExternalToken(rs.getString(1), "twitter", - rs.getString(2), rs.getString(3)), - uid); - - return list.isEmpty() ? - Optional.empty() : Optional.of(list.get(0)); - } - - @Transactional - @Override - public boolean deleteTwitterToken(Integer uid) { - return getJdbcTemplate().update("DELETE FROM twitter WHERE user_id=?", uid) > 0 - && getJdbcTemplate().update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=1741", uid) > 0; - } - - @Override - public void addFacebookState(String state) { - jdbcTemplate.update("INSERT INTO facebook(loginhash) VALUES(?)", state); - } - - @Override - public boolean verifyFacebookState(String state) { - try { - return jdbcTemplate.queryForObject("SELECT COUNT(loginhash) FROM facebook WHERE loginhash=?", - Integer.class, state) == 1; - } catch (EmptyResultDataAccessException e) { - return false; - } - } - - @Transactional(readOnly = true) - @Override - public Optional<Pair<String, String>> getFacebookTokens(final int uid) { - List<Optional<Pair<String, String>>> list = getJdbcTemplate().query( - "SELECT fb_id, access_token FROM facebook WHERE user_id = ? AND access_token IS NOT NULL AND crosspost = 1", - (rs, num) -> Optional.of(Pair.of(rs.getString(1), rs.getString(2))), - uid); - return list.isEmpty() ? - Optional.empty() : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public ApplicationStatus getFbCrossPostStatus(final int uid) { - List<ApplicationStatus> list = getJdbcTemplate().query( - "SELECT 1, crosspost FROM facebook WHERE user_id = ? LIMIT 1", - (rs, num) -> { - ApplicationStatus status = new ApplicationStatus(); - - status.setConnected(rs.getInt(1) > 0); - status.setCrosspostEnabled(rs.getBoolean(2)); - - return status; - }, - uid); - - return list.isEmpty() ? - new ApplicationStatus() : list.get(0); - } - - @Transactional - @Override - public boolean enableFBCrosspost(Integer uid) { - return getJdbcTemplate().update("UPDATE facebook SET crosspost=1 WHERE user_id=?", uid) > 0 - && getJdbcTemplate().update( - "INSERT INTO subscr_users(user_id,suser_id,jid,active) VALUES (?,5863,'juick@facebook.juick.com',1)", - uid) > 0; - } - - @Transactional - @Override - public void disableFBCrosspost(Integer uid) { - getJdbcTemplate().update("UPDATE facebook SET crosspost=0 WHERE user_id=?", uid); - // TODO: stop using magic numbers for system users - getJdbcTemplate().update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=5863", uid); - } - - @Transactional(readOnly = true) - @Override - public String getTwitterName(final int uid) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT uname FROM twitter WHERE user_id = ?", - String.class, - uid); - - return list.isEmpty() ? - StringUtils.EMPTY : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public String getTelegramName(final int uid) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT tg_name FROM telegram WHERE user_id = ?", - String.class, - uid); - - return list.isEmpty() ? - StringUtils.EMPTY : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public Optional<Pair<String, String>> getVkTokens(final int uid) { - List<Optional<Pair<String, String>>> list = getJdbcTemplate().query( - "SELECT vk_id, access_token FROM vk WHERE user_id = ? AND crosspost = 1", - (rs, num) -> Optional.of(Pair.of(rs.getString(1), rs.getString(2))), - uid); - - return list.isEmpty() ? - Optional.empty() : list.get(0); - } - - @Transactional - @Override - public void deleteVKUser(Integer uid) { - getJdbcTemplate().update("DELETE FROM vk WHERE user_id=?", uid); - } - - @Transactional(readOnly = true) - @Override - public int getUIDbyFBID(long fbID) { - try { - return getJdbcTemplate().queryForObject("SELECT user_id FROM facebook WHERE fb_id=? AND user_id IS NOT NULL", - Integer.class, fbID); - } catch (EmptyResultDataAccessException e) { - return 0; - } - } - - @Transactional - @Override - public boolean createFacebookUser(long fbID, String loginhash, String token, String fbName, String fbLink) { - return getJdbcTemplate().update("UPDATE facebook SET fb_id=?, access_token=?, fb_name=?, fb_link=? WHERE loginhash=?", - fbID, token, fbName, fbLink, loginhash) > 0; - } - - @Transactional - @Override - public boolean updateFacebookUser(long fbID, String token, String fbName, String fbLink) { - return getJdbcTemplate().update("UPDATE facebook SET access_token=?,fb_name=?,fb_link=? WHERE fb_id=?", - token, fbName, fbLink, fbID) > 0; - } - - @Transactional(readOnly = true) - @Override - public int getUIDbyVKID(long vkID) { - try { - return getJdbcTemplate().queryForObject("SELECT user_id FROM vk WHERE vk_id=? AND user_id IS NOT NULL", Integer.class, vkID); - } catch (EmptyResultDataAccessException e) { - return 0; - } - } - - @Transactional - @Override - public boolean createVKUser(long vkID, String loginhash, String token, String vkName, String vkLink) { - return getJdbcTemplate().update("INSERT INTO vk(vk_id,loginhash,access_token,vk_name,vk_link) VALUES (?,?,?,?,?)", - vkID, loginhash, token, vkName, vkLink) > 0; - } - - @Transactional(readOnly = true) - @Override - public String getFacebookNameByHash(String hash) { - try { - List<Pair<String, String>> fb = getJdbcTemplate().query("SELECT fb_name,fb_link FROM facebook WHERE loginhash=?", - (rs, num) -> Pair.of(rs.getString(1), rs.getString(2)), hash); - if (fb.size() > 0) { - return "<a href=\"" + fb.get(0).getRight() + "\" rel=\"nofollow\">" + fb.get(0).getLeft() + "</a>"; - } - return null; - } catch (EmptyResultDataAccessException e) { - return null; - } - } - - @Transactional - @Override - public String getTelegramNameByHash(String hash) { - try { - String name = getJdbcTemplate().queryForObject("SELECT tg_name FROM telegram WHERE loginhash=?", String.class, hash); - return "<a href=\"https://telegram.me/" + name + "\" rel=\"nofollow\">" + name + "</a>"; - } catch (EmptyResultDataAccessException e) { - return null; - } - } - - @Transactional - @Override - public boolean setFacebookUser(String hash, int uid) { - return getJdbcTemplate().update("UPDATE facebook SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0; - } - - @Transactional - @Override - public String getVKNameByHash(String hash) { - List<Pair<String, String>> logins = getJdbcTemplate().query("SELECT vk_name,vk_link FROM vk WHERE loginhash=?", - (rs, num) -> Pair.of(rs.getString(1), rs.getString(2)), hash); - if (logins.size() > 0) { - return "<a href=\"http://vk.com/" + logins.get(0).getRight() + "\" rel=\"nofollow\">" + logins.get(0).getLeft() + "</a>"; - } - return null; - } - - @Transactional - @Override - public boolean setVKUser(String hash, int uid) { - return getJdbcTemplate().update("UPDATE vk SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0; - } - - @Transactional - @Override - public boolean setTelegramUser(String hash, int uid) { - return getJdbcTemplate().update("UPDATE telegram SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0; - } - - @Transactional(readOnly = true) - @Override - public String getJIDByHash(String hash) { - try { - return getJdbcTemplate().queryForObject("SELECT jid FROM jids WHERE loginhash=?", String.class, hash); - } catch (EmptyResultDataAccessException e) { - return null; - } - } - - @Transactional - @Override - public boolean setJIDUser(String hash, int uid) { - return getJdbcTemplate().update("UPDATE jids SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/EmailServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/EmailServiceImpl.java deleted file mode 100644 index 0cccc9156..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/EmailServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import javax.inject.Inject; -import java.util.List; - -/** - * Created by vitalyster on 09.12.2016. - */ -@Repository -@Transactional -public class EmailServiceImpl extends BaseJdbcService implements EmailService { - - @Override - public boolean verifyAddressByCode(Integer userId, String code) { - try { - String address = getJdbcTemplate().queryForObject("SELECT account FROM auth WHERE user_id=? AND protocol='email' AND authcode=?", - String.class, userId, code); - addEmail(userId, address); - getJdbcTemplate().update("DELETE FROM auth WHERE user_id=? AND authcode=?", userId, code); - } catch (EmptyResultDataAccessException e) { - return false; - } - return true; - } - - @Override - public boolean addVerificationCode(Integer userId, String account, String code) { - return getJdbcTemplate().update("INSERT INTO auth(user_id,protocol,account,authcode) VALUES (?,'email',?,?)", - userId, account, code) > 0; - } - - @Override - public boolean addEmail(Integer userId, String email) { - return getJdbcTemplate().update("INSERT INTO emails(user_id,email) VALUES (?,?)", userId, email) > 0; - } - - @Override - public boolean deleteEmail(Integer userId, String account) { - return getNamedParameterJdbcTemplate().update("DELETE FROM emails " + - "WHERE (SELECT COUNT(*) cnt FROM (select user_id, email FROM emails e) c WHERE user_id=:uid) > 1 " + - "AND user_id=:uid AND email=:email", - new MapSqlParameterSource() - .addValue("uid", userId) - .addValue("email", account)) > 0; - } - - @Transactional(readOnly = true) - @Override - public String getNotificationsEmail(Integer userId) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT email FROM emails WHERE user_id=? AND subscr_hour IS NOT NULL", String.class, userId); - return list.isEmpty() ? StringUtils.EMPTY : list.get(0); - } - - @Override - public boolean setNotificationsEmail(Integer userId, String account) { - getJdbcTemplate().update("UPDATE emails SET subscr_hour=NULL WHERE user_id=?", userId); - return StringUtils.isNotEmpty(account) && getJdbcTemplate().update( - "UPDATE emails SET subscr_hour=1 WHERE user_id=? AND email=?", userId, account) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getEmails(Integer userId, boolean active) { - return getJdbcTemplate().queryForList("SELECT email FROM emails WHERE user_id=? " + - (active ? "AND subscr_hour IS NOT NULL" : ""), String.class, userId); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java deleted file mode 100644 index 35e483833..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.*; -import com.juick.server.helpers.PrivacyOpts; -import com.juick.server.helpers.ResponseReply; -import com.juick.util.MessageUtils; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.dao.IncorrectResultSizeDataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; -import org.springframework.jdbc.core.simple.SimpleJdbcInsert; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import javax.inject.Inject; -import java.sql.*; -import java.time.Instant; -import java.util.*; -import java.util.Date; -import java.util.stream.Collectors; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class MessagesServiceImpl extends BaseJdbcService implements MessagesService { - private static final Logger logger = LoggerFactory.getLogger(MessagesServiceImpl.class); - @Inject - private UserService userService; - @Inject - private TagService tagService; - @Inject - private SearchService searchService; - @Inject - private ImagesService imagesService; - @Value("${img_url:https://i.juick.com/}") - private String baseImagesUrl; - - private class MessageMapper implements RowMapper<Message> { - @Override - public Message mapRow(ResultSet rs, int rowNum) throws SQLException { - Message msg = new Message(); - msg.setMid(rs.getInt(1)); - msg.setRid(rs.getInt(2)); - msg.setReplyto(rs.getInt(3)); - User user = new User(); - user.setUid(rs.getInt(4)); - user.setName(rs.getString(5)); - user.setBanned(rs.getBoolean(6)); - msg.setUser(user); - msg.setTimestamp(rs.getTimestamp(7).toInstant()); - msg.ReadOnly = rs.getBoolean(8); - msg.setPrivacy(rs.getInt(9)); - msg.FriendsOnly = msg.getPrivacy() < 0; - msg.setReplies(rs.getInt(10)); - msg.setAttachmentType(rs.getString(11)); - msg.setLikes(rs.getInt(12)); - msg.Hidden = rs.getBoolean(13); - String tagsStr = rs.getString(14); - msg.setTags(MessageUtils.parseTags(tagsStr)); - msg.setRepliesBy(rs.getString(15)); - msg.setText(rs.getString(16)); - msg.setReplyQuote(MessageUtils.formatQuote(rs.getString(17))); - msg.setUpdated(rs.getTimestamp(18).toInstant()); - int quoteUid = rs.getInt(19); - if (quoteUid > 0) { - User quoteUser = new User(); - quoteUser.setUid(quoteUid); - quoteUser.setName(rs.getString(20)); - msg.setTo(quoteUser); - } - if (StringUtils.isNotEmpty(msg.getAttachmentType())) { - try { - imagesService.setAttachmentMetadata(baseImagesUrl, msg); - } catch (Exception e) { - logger.warn("exception reading images for mid {} rid {}", msg.getMid(), msg.getRid(), e); - } - } - return msg; - } - } - - - - /** - * @see <a href="https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-type-conversions.html">Java, JDBC and MySQL Types</a> - */ - @Transactional - @Override - public int createMessage(final int uid, final String txt, final String attachment, final Collection<com.juick.Tag> tags) { - SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(getJdbcTemplate()).withTableName("messages") - .usingColumns("user_id", "attach", "ts") - .usingGeneratedKeyColumns("message_id"); - Map<String, Object> insertMap = new HashMap<>(); - insertMap.put("user_id", uid); - Instant now = Instant.now(); - insertMap.put("ts", Timestamp.from(now)); - if (attachment != null) { - insertMap.put("attach", attachment); - } - int mid = simpleJdbcInsert.executeAndReturnKey(insertMap).intValue(); - if (mid > 0) { - String tagsNames = StringUtils.EMPTY; - - if (CollectionUtils.isNotEmpty(tags)) { - StringBuilder tasNamesBuilder = new StringBuilder(); - List<Object[]> params = new ArrayList<>(tags.size()); - - boolean next = false; - - for (Tag tag : tags) { - if (next) { - tasNamesBuilder.append(" "); - } else - next = true; - - tasNamesBuilder.append(tag.getName()); - params.add(new Object[]{mid, tag.TID}); - } - tagsNames = tasNamesBuilder.toString(); - - getJdbcTemplate().batchUpdate( - "INSERT INTO messages_tags(message_id, tag_id) VALUES (?, ?)", - params, new int[]{Types.INTEGER, Types.INTEGER}); - } - - getJdbcTemplate().update( - "INSERT INTO messages_txt(message_id, tags, txt) VALUES (?, ?, ?)", - new Object[]{mid, tagsNames, txt}, - new int[]{Types.INTEGER, Types.VARCHAR, Types.VARCHAR}); - getJdbcTemplate().update("UPDATE users SET lastmessage=? where id=?", Timestamp.from(now), uid); - } - - return mid; - } - - /** - * @param mid - * @param rid - * @param user - * @param txt - * @param attachment - * @return - * @see <a href="https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-type-conversions.html">Java, JDBC and MySQL Types</a> - */ - @Transactional - @Override - public int createReply(final int mid, final int rid, final User user, final String txt, final String attachment) { - int ridnew = getReplyIDIncrement(mid); - Date ts = Date.from(Instant.now()); - getJdbcTemplate().update("INSERT INTO replies(message_id, reply_id, user_id, replyto, attach, txt, ts) " + - "VALUES (?, ?, ?, ?, ?, ?, ?)", - mid, ridnew, user.getUid(), rid, attachment, txt, ts); - - if (ridnew > 0) { - getJdbcTemplate().update( - "UPDATE messages SET replies = replies + 1, updated=? WHERE message_id = ?", - ts, mid); - setLastReadComment(user, mid, ridnew); - getJdbcTemplate().update("UPDATE users SET lastmessage=? where id=?", ts, user.getUid()); - } - return ridnew; - } - - @Override - public int getReplyIDIncrement(final int mid) { - return getJdbcTemplate().execute((ConnectionCallback<Integer>) conn -> { - conn.setAutoCommit(false); - final int replyNo; - try (PreparedStatement ps = conn.prepareStatement("SELECT maxreplyid+1 FROM messages WHERE message_id=? FOR UPDATE")) { - ps.setInt(1, mid); - try (ResultSet resultSet = ps.executeQuery()) { - if (resultSet.next()) { - replyNo = resultSet.getInt(1); - } else { - throw new IncorrectResultSizeDataAccessException("while getting getReplyIDIncrement, mid=" + mid, 1, 0); - } - } - } - try (PreparedStatement ps = conn.prepareStatement("UPDATE messages SET maxreplyid=? WHERE message_id=?")) { - ps.setInt(1, replyNo); - ps.setInt(2, mid); - if (ps.executeUpdate() != 1) { - throw new IncorrectResultSizeDataAccessException("Cannot find a message to update: " + mid, 1, 0); - } - } - conn.commit(); - return replyNo; - }); - - } - - @Transactional - void updateRepliesBy(int mid) { - List<String> users = getJdbcTemplate().queryForList("SELECT users.nick FROM replies " + - "INNER JOIN users ON replies.user_id=users.id WHERE replies.message_id=? " + - "GROUP BY replies.user_id ORDER BY COUNT(replies.reply_id) DESC LIMIT 5", String.class, mid); - String result = users.stream().map(u -> "@" + u).collect(Collectors.joining(",")); - getJdbcTemplate().update("UPDATE messages_txt SET repliesby=? WHERE message_id=?", result, mid); - } - - @Transactional - @Override - public RecommendStatus recommendMessage(final int mid, final int vuid) { - int wasDeleted = getJdbcTemplate() - .update("DELETE FROM favorites WHERE user_id=? AND message_id=? and like_id=?", vuid, mid, Reaction.LIKE); - if (wasDeleted > 0) { - return RecommendStatus.Deleted; - } else { - boolean wasAdded = getJdbcTemplate() - .update("INSERT INTO favorites(user_id, message_id, ts, like_id ) VALUES (?, ?, NOW(), ?)", vuid, mid,Reaction.LIKE) == 1; - if (wasAdded) { - return RecommendStatus.Added; - } - } - return RecommendStatus.Error; - } - - @Override - public List<Reaction> listReactions() { - return jdbcTemplate.query("SELECT like_id, description FROM reactions", (rs, rowNum) -> { - Reaction reaction = new Reaction(rs.getInt("like_id")); - reaction.setDescription(rs.getString("description")); - return reaction; - }); - } - - @Transactional - @Override - public RecommendStatus likeMessage(int mid, int vuid, int reactionId) throws IllegalArgumentException { - boolean wasAdded = getJdbcTemplate() - .update("INSERT INTO favorites(user_id, message_id, ts, like_id ) VALUES (?, ?, NOW(), ?)", vuid, mid, reactionId) == 1; - if (wasAdded) { - return RecommendStatus.Added; - } - - return RecommendStatus.Error; - } - - @Transactional(readOnly = true) - @Override - public boolean canViewThread(final int mid, final int uid) { - List<PrivacyOpts> list = getJdbcTemplate().query( - "SELECT user_id, privacy FROM messages WHERE message_id = ?", - (rs, rowNum) -> { - PrivacyOpts res = new PrivacyOpts(); - - res.setUid(rs.getInt(1)); - res.setPrivacy(rs.getInt(2)); - - return res; - }, - mid); - - PrivacyOpts privacyOpts = list.isEmpty() ? null : list.get(0); - - return privacyOpts == null || - privacyOpts.getPrivacy() >= 0 || - uid == privacyOpts.getUid() || - ((privacyOpts.getPrivacy() == -1 || privacyOpts.getPrivacy() == -2) && - uid > 0 && userService.isInWL(privacyOpts.getUid(), uid)); - } - - @Transactional(readOnly = true) - @Override - public boolean isReadOnly(final int mid) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT readonly FROM messages WHERE message_id = ?", - new Object[]{mid}, - Integer.class); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public boolean isSubscribed(final int uid, final int mid) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM subscr_messages WHERE suser_id = ? AND message_id = ?", - new Object[]{uid, mid}, - Integer.class); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public int getMessagePrivacy(final int mid) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT privacy FROM messages WHERE message_id = ?", - new Object[]{mid}, - Integer.class); - - return list.isEmpty() ? -4 : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public com.juick.Message getMessage(final int mid) { - - List<com.juick.Message> list = getJdbcTemplate().query( - "SELECT messages.message_id as mid, 0 as rid, 0 as replyto, " - + "messages.user_id as uid, users.nick, users.banned as banned, " - + "" - + "messages.ts," - + "messages.readonly, messages.privacy, messages.replies," - + "messages.attach, COUNT(DISTINCT favorites.user_id) as likes, messages.hidden," - + "txt.tags, txt.repliesby, txt.txt, '' as q, messages.updated, 0 as to_uid, " - + "NULL as to_name FROM messages " - + "INNER JOIN users ON messages.user_id = users.id " - + "INNER JOIN messages_txt AS txt " - + "ON messages.message_id = txt.message_id " - + "LEFT JOIN favorites " - + "ON messages.message_id = favorites.message_id AND favorites.like_id=1 " - + "WHERE messages.message_id = ? " - + "GROUP BY mid, rid, replyto, uid, nick, banned, messages.ts, readonly, " - + "privacy, replies, attach, tags, repliesby, q", - new MessageMapper(), - mid); - if (!list.isEmpty()) { - final Message message = list.get(0); - Map<Integer, Set<Reaction>> reactionStats = updateReactionsFor(Collections.singletonList(mid)); - message.setReactions(reactionStats.get(message.getMid())); - return message; - } - return null; - } - - @Transactional(readOnly = true) - @Override - public com.juick.Message getReply(final int mid, final int rid) { - List<com.juick.Message> list = getJdbcTemplate().query( - "SELECT replies.user_id, users.nick," - + "replies.replyto, replies.ts," - + "replies.attach, replies.txt, IFNULL(q.txt,t.txt) as quote, " - + "COALESCE(q.user_id, m.user_id) AS to_uid, COALESCE(qu.nick, mu.nick) AS to_name " - + "FROM replies INNER JOIN users ON replies.user_id = users.id " - + "LEFT JOIN replies q ON replies.message_id = q.message_id and replies.replyto = q.reply_id " - + "LEFT JOIN messages_txt t ON replies.message_id = t.message_id " - + "LEFT JOIN messages m ON replies.message_id = m.message_id " - + "LEFT JOIN users qu ON q.user_id=qu.id " - + "LEFT JOIN users mu ON m.user_id=mu.id " - + "WHERE replies.message_id = ? AND replies.reply_id = ?", - (rs, num) -> { - Message msg = new Message(); - - msg.setMid(mid); - msg.setRid(rid); - msg.setUser(new User()); - msg.getUser().setUid(rs.getInt(1)); - msg.getUser().setName(rs.getString(2)); - msg.setReplyto(rs.getInt(3)); - msg.setTimestamp(rs.getTimestamp(4).toInstant()); - msg.setAttachmentType(rs.getString(5)); - msg.setText(rs.getString(6)); - String quote = rs.getString(7); - - if (!StringUtils.isEmpty(quote)) { - msg.setReplyQuote(MessageUtils.formatQuote(quote)); - } - int quoteUid = rs.getInt(8); - if (quoteUid > 0) { - User quoteUser = new User(); - quoteUser.setUid(quoteUid); - quoteUser.setName(rs.getString(9)); - msg.setTo(quoteUser); - } - - return msg; - }, - mid, rid); - - return list.isEmpty() ? null : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public User getMessageAuthor(final int mid) { - List<User> list = getJdbcTemplate().query( - "SELECT messages.user_id, users.nick " - + "FROM messages INNER JOIN users ON messages.user_id = users.id WHERE messages.message_id = ?", - new Object[]{mid}, - (rs, num) -> { - User res = new com.juick.User(); - res.setUid(rs.getInt(1)); - res.setName(rs.getString(2)); - return res; - }); - - return list.isEmpty() ? - null : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public List<String> getMessageRecommendations(final int mid) { - return getJdbcTemplate().queryForList( - "SELECT DISTINCT users.nick FROM favorites INNER JOIN users " + - "ON (favorites.message_id = ? AND favorites.user_id = users.id) WHERE favorites.like_id=1", - new Object[]{mid}, - String.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getAll(final int visitorUid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("before", before) - .addValue("visitorUid", visitorUid); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT m.message_id FROM messages m WHERE " + - (before > 0 ? - " m.message_id < :before AND " : StringUtils.EMPTY) + - " m.hidden = 0 AND (m.privacy > 0" + - (visitorUid > 1 ? - " OR m.user_id = :visitorUid) AND NOT EXISTS (" + - " SELECT 1 FROM bl_users b WHERE b.user_id = :visitorUid AND b.bl_user_id = m.user_id)" : - ")") + - " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " + - "(SELECT tag_id FROM messages_tags WHERE message_id = m.message_id) and :visitorUid = bt.user_id)" + - " AND NOT EXISTS (SELECT 1 from users u WHERE u.banned = 1 and u.id = m.user_id) ORDER BY m.message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getTag(final int tid, final int visitorUid, final int before, final int cnt) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("tid", tid) - .addValue("cnt", cnt) - .addValue("before", before) - .addValue("visitorUid", visitorUid); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM (tags INNER JOIN messages_tags " + - "ON ((tags.synonym_id = :tid OR tags.tag_id = :tid) AND tags.tag_id = messages_tags.tag_id)) " + - "INNER JOIN messages USING(message_id) WHERE " + - (before > 0 ? - " messages.message_id < :before AND " : StringUtils.EMPTY) + - "(messages.privacy > 0 OR messages.user_id = :visitorUid) ORDER BY message_id DESC LIMIT :cnt", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getTags(final String tids, final int visitorUid, final int before, final int cnt) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("cnt", cnt) - .addValue("before", before) - .addValue("visitorUid", visitorUid); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT messages.message_id FROM messages_tags " + - "INNER JOIN messages USING(message_id) WHERE messages_tags.tag_id IN (" + tids + ") " + - (before > 0 ? - " AND messages.message_id < :before " : StringUtils.EMPTY) + - " AND (messages.privacy > 0 OR messages.user_id = :visitorUid) " + - "ORDER BY messages.message_id DESC LIMIT :cnt", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getPlace(final int placeId, final int visitorUid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("placeId", placeId) - .addValue("before", before) - .addValue("visitorUid", visitorUid); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE place_id = :placeId " + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - " AND (privacy > 0 OR user_id = :visitorUid) ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getMyFeed(final int uid, final int before, boolean recommended) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("before", before); - - List<Integer> mids = getNamedParameterJdbcTemplate().queryForList( - "(SELECT message_id FROM messages " + - " INNER JOIN subscr_users ON (subscr_users.suser_id = :uid AND subscr_users.user_id = messages.user_id) " + - " WHERE " + - (before > 0 ? - " message_id < :before AND " : StringUtils.EMPTY) + - " (privacy >= 0 OR (privacy >= -2 AND privacy <= -1" + - " AND EXISTS (SELECT 1 FROM wl_users w WHERE w.wl_user_id = :uid and w.user_id = messages.user_id)))) " + - " UNION " + - " (SELECT message_id FROM messages WHERE user_id=:uid " + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - (recommended ? - ") UNION " + - " (SELECT f.message_id as message_id FROM favorites f WHERE " + - "EXISTS (SELECT 1 FROM subscr_users s WHERE s.suser_id = :uid and f.user_id = s.user_id)" + - (before > 0 ? - " AND f.message_id < :before " : StringUtils.EMPTY) : StringUtils.EMPTY) + - ") ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - - return mids; - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getPrivate(final int uid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList - ("SELECT message_id FROM messages WHERE user_id = :uid AND privacy < 0" + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - "ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getDiscussions(final int uid, final Long to) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("to", new Timestamp(to)); - - return getNamedParameterJdbcTemplate().query( - "SELECT messages.message_id, messages.updated FROM subscr_messages " + - "INNER JOIN messages ON messages.message_id=subscr_messages.message_id " + - "WHERE suser_id = :uid " + - (to != 0 ? - "AND updated < :to " : StringUtils.EMPTY) + - "ORDER BY updated DESC, message_id DESC LIMIT 20", - sqlParameterSource, - (rs, rowNum) -> rs.getInt(1)); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getRecommended(final int uid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT f.message_id FROM favorites f WHERE " + - "EXISTS (SELECT 1 FROM subscr_users s WHERE s.suser_id = :uid and f.user_id = s.user_id)" + - (before > 0 ? - " AND f.message_id < :before " : StringUtils.EMPTY) + - "ORDER BY f.message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getPopular(final int visitorUid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("vid", visitorUid) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT m.message_id FROM messages m WHERE m.privacy > 0 " + - (before > 0 ? - " AND m.message_id < :before " : StringUtils.EMPTY) + - " AND m.popular > 0 AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.user_id = :vid and b.bl_user_id = m.user_id) " + - " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " + - "(SELECT tag_id FROM messages_tags WHERE message_id = m.message_id) and :vid = bt.user_id)" + - " ORDER BY m.message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getPhotos(final int visitorUid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("vid", visitorUid) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT m.message_id FROM messages m WHERE (m.privacy > 0 OR m.user_id = :vid) " + - (before > 0 ? - " AND m.message_id < :before " : StringUtils.EMPTY) + - " AND m.attach IS NOT NULL " + - " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " + - "(SELECT tag_id FROM messages_tags WHERE message_id = m.message_id) and :vid = bt.user_id)" + - " AND NOT EXISTS (SELECT 1 from users u WHERE u.banned = 1 and u.id = m.user_id) " + - " AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.user_id = :vid and b.bl_user_id = m.user_id) " + - " ORDER BY m.message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getSearch(final String search, final int before) { - List<Integer> mids = searchService.searchInAllMessages(search, before); - - if (!mids.isEmpty()) - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE message_id IN (:ids) AND privacy > 0 ORDER BY message_id DESC LIMIT 20", - new MapSqlParameterSource("ids", mids), - Integer.class); - return mids; - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserBlog(final int uid, final int privacy, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("privacy", privacy) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE user_id = :uid" + - (before > 0 ? - " AND message_id < :before" : StringUtils.EMPTY) + - " AND privacy >= :privacy ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserTag(final int uid, final int tid, final int privacy, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("tid", tid) - .addValue("privacy", privacy) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT messages.message_id FROM messages_tags INNER JOIN messages " + - " USING (message_id) WHERE messages.user_id = :uid AND messages_tags.tag_id = :tid " + - (before > 0 ? - " AND messages.message_id < :before " : StringUtils.EMPTY) + - " AND messages.privacy >= :privacy ORDER BY messages.message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserBlogAtDay(final int uid, final int privacy, final int daysback) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("privacy", privacy) - .addValue("daysback", daysback); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE user_id = :uid" + - (daysback > 0 ? - " AND ts >= date(NOW() - INTERVAL :daysback day)" + - " AND ts < date(NOW() - INTERVAL :daysback day + INTERVAL 1 day)" : StringUtils.EMPTY) + - " AND privacy >= :privacy ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserBlogWithRecommendations(final int uid, final int privacy, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("privacy", privacy) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM " + - "(SELECT message_id FROM favorites " + - " WHERE user_id = :uid " + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - " ORDER BY message_id DESC LIMIT 20) as r" + - " UNION ALL " + - "SELECT message_id FROM " + - "(SELECT message_id FROM messages WHERE user_id = :uid" + - (before > 0 ? - " AND message_id < :before" : StringUtils.EMPTY) + - " AND privacy >= :privacy ORDER BY message_id DESC LIMIT 20) as m " + - "ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserRecommendations(final int uid, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM favorites " + - " WHERE user_id = :uid " + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - " ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserPhotos(final int uid, final int privacy, final int before) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("privacy", privacy) - .addValue("before", before); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE user_id = :uid " + - (before > 0 ? - " AND message_id < :before " : StringUtils.EMPTY) + - " AND privacy >= :privacy AND attach IS NOT NULL ORDER BY message_id DESC LIMIT 20", - sqlParameterSource, - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserSearch(final int UID, final String search, final int privacy, final int before) { - List<Integer> mids = searchService.searchByStringAndUser(search, UID, before); - - if (!mids.isEmpty()) { - return getNamedParameterJdbcTemplate().queryForList( - "SELECT message_id FROM messages WHERE message_id IN (:ids) AND privacy >= :privacy ORDER BY message_id DESC", - new MapSqlParameterSource("ids", mids) - .addValue("privacy", privacy), - Integer.class); - } - return mids; - } - - @Transactional(readOnly = true) - @Override - public List<com.juick.Message> getMessages(final List<Integer> mids) { - if (CollectionUtils.isNotEmpty(mids)) { - - List<com.juick.Message> msgs = getNamedParameterJdbcTemplate().query( - "SELECT messages.message_id, 0 as rid, 0 as replyto, " - + "messages.user_id,users.nick, 0 as banned, " - + "messages.ts," - + "messages.readonly,messages.privacy,messages.replies," - + "messages.attach,COUNT(DISTINCT favorites.user_id) AS likes,messages.hidden," - + "messages_txt.tags,messages_txt.repliesby, messages_txt.txt, '' as q, " - + "messages.updated, 0 as to_uid, NULL as to_name " - + "FROM (messages INNER JOIN messages_txt " - + "ON messages.message_id=messages_txt.message_id) " - + "INNER JOIN users ON messages.user_id=users.id " - + "LEFT JOIN favorites " - + "ON messages.message_id = favorites.message_id AND favorites.like_id=1 " - + "WHERE messages.message_id IN (:ids) GROUP BY messages.message_id", - new MapSqlParameterSource("ids", mids), - new MessageMapper()); - - - Map<Integer,Set<Reaction>> likes = updateReactionsFor(mids); - - msgs.forEach(i -> i.setReactions(likes.get(i.getMid()))); - - msgs.sort(Comparator.comparing(item -> mids.indexOf(item.getMid()))); - - return msgs; - } - return Collections.emptyList(); - } - - - @Transactional(readOnly = true) - @Override - public Map<Integer,Set<Reaction>> updateReactionsFor(final List<Integer> mids) { - - return getNamedParameterJdbcTemplate().query("select f.message_id as mid, f.like_id as lid," + - " r.description as descr, count(f.like_id) as cnt" + - " from favorites f LEFT JOIN reactions r ON f.like_id = r.like_id " + - " where f.message_id IN (:mids) " + - " group by f.message_id, f.like_id", new MapSqlParameterSource("mids", mids), (ResultSet rs) -> { - Map<Integer,Set<Reaction>> results = new HashMap<>(); - - - while (rs.next()) { - int messageId = rs.getInt("mid"); - int likeId = rs.getInt("lid"); - int count = rs.getInt("cnt"); - String description = rs.getString("descr"); - Reaction reaction = new Reaction(likeId); - reaction.setCount(count); - reaction.setDescription(description); - results.computeIfAbsent(messageId, HashSet::new); - results.get(messageId).add(reaction); - } - - return results; - }); - - } - - - @Transactional - @Override - public List<Message> getReplies(final User user, final int mid) { - List<Message> replies = getNamedParameterJdbcTemplate().query( - "SELECT replies.message_id as mid, replies.reply_id, replies.replyto, " + - "replies.user_id, users.nick, users.banned, " + - "replies.ts, " + - "0 as readonly, 0 as privacy, 0 as replies, " + - "replies.attach, 0 as likes, 0 as hidden, " + - "NULL as tags, NULL as repliesby, replies.txt, " + - "IFNULL(qw.txt, t.txt) as q, " + - "NOW(), " + - "COALESCE(qw.user_id, m.user_id) as to_uid, COALESCE(qu.nick, mu.nick) as to_name " + - "FROM replies INNER JOIN users " + - "ON replies.user_id = users.id " + - "LEFT JOIN replies qw ON replies.message_id = qw.message_id and replies.replyto = qw.reply_id " + - "LEFT JOIN messages_txt t on replies.message_id = t.message_id " + - "LEFT JOIN messages m on replies.message_id = m.message_id " + - "LEFT JOIN users qu ON qw.user_id=qu.id " + - "LEFT JOIN users mu ON m.user_id=mu.id " + - "WHERE replies.message_id = :mid ORDER BY replies.reply_id ASC", - new MapSqlParameterSource("mid", mid), - new MessageMapper()); - if (replies.size() > 0) { - setLastReadComment(user, mid, replies.stream().map(Message::getRid).max(Comparator.naturalOrder()).get()); - } - return replies; - } - - @Transactional - @Override - public boolean setMessagePopular(final int mid, final int popular) { - int ret; - MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("mid", mid) - .addValue("popular", popular); - - switch (popular) { - case -2: - ret = getNamedParameterJdbcTemplate().update( - "UPDATE messages SET hidden = 1 WHERE message_id = :mid", - sqlParameterSource); - break; - case -1: - sqlParameterSource.addValue("popular", 0); - default: - ret = getNamedParameterJdbcTemplate().update( - "UPDATE messages SET popular = :popular WHERE message_id = :mid", - sqlParameterSource); - break; - } - - if (popular == -1) - ret = getNamedParameterJdbcTemplate().update( - "INSERT INTO top_ignore_messages VALUES (:mid)", - sqlParameterSource); - - return ret > 0; - } - - @Transactional - @Override - public boolean setMessagePrivacy(final int mid) { - return getJdbcTemplate().update("UPDATE messages SET privacy=1 WHERE message_id=?", mid) > 0; - } - - @Transactional - @Override - public boolean deleteMessage(final int uid, final int mid) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("mid", mid) - .addValue("uid", uid); - - if (getNamedParameterJdbcTemplate().update( - "DELETE FROM messages WHERE message_id = :mid AND user_id = :uid", sqlParameterSource) > 0) { - - getNamedParameterJdbcTemplate().update("DELETE FROM messages_txt WHERE message_id = :mid", sqlParameterSource); - getNamedParameterJdbcTemplate().update("DELETE FROM replies WHERE message_id = :mid", sqlParameterSource); - getNamedParameterJdbcTemplate().update("DELETE FROM subscr_messages WHERE message_id = :mid", sqlParameterSource); - getNamedParameterJdbcTemplate().update("DELETE FROM messages_tags WHERE message_id = :mid", sqlParameterSource); - - return true; - } - return false; - } - @Transactional - @Override - public boolean deleteReply(final int uid, final int mid, final int rid) { - User author = getMessageAuthor(mid); - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("mid", mid) - .addValue("uid", uid) - .addValue("rid", rid); - boolean result; - if (author.getUid() == uid) { - result = getNamedParameterJdbcTemplate() - .update("DELETE FROM replies WHERE message_id=:mid AND reply_id=:rid", sqlParameterSource) > 0; - } else { - result = getNamedParameterJdbcTemplate() - .update("DELETE FROM replies WHERE message_id=:mid AND reply_id=:rid AND user_id=:uid" - , sqlParameterSource) > 0; - } - if (result) { - getNamedParameterJdbcTemplate().update("UPDATE messages SET replies=replies-1 WHERE message_id=:mid", sqlParameterSource); - updateRepliesBy(mid); - return true; - } - return false; - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getLastMessages(int hours) { - return getJdbcTemplate().queryForList("SELECT message_id FROM messages WHERE messages.ts>TIMESTAMPADD(HOUR,?,NOW())", - Integer.class, -hours); - - } - - @Transactional(readOnly = true) - @Override - public List<ResponseReply> getLastReplies(int hours) { - return getJdbcTemplate().query("SELECT users2.nick,replies.message_id,replies.reply_id," + - "users.nick,replies.txt," + - "replies.ts,replies.attach,replies.ts+0 " + - "FROM ((replies INNER JOIN users ON replies.user_id=users.id) " + - "INNER JOIN messages ON replies.message_id=messages.message_id) " + - "INNER JOIN users AS users2 ON messages.user_id=users2.id " + - "WHERE replies.ts>TIMESTAMPADD(HOUR,?,NOW()) AND messages.privacy>0", (rs, rowNum) -> { - ResponseReply reply = new ResponseReply(); - reply.setMuname(rs.getString(1)); - reply.setMid(rs.getInt(2)); - reply.setRid(rs.getInt(3)); - reply.setUname(rs.getString(4)); - reply.setDescription(rs.getString(5)); - reply.setPubDate(rs.getTimestamp(6)); - reply.setAttachmentType(rs.getString(7)); - return reply; - }, -hours); - } - @Transactional(readOnly = true) - @Override - public List<Integer> getPopularCandidates() { - return getJdbcTemplate().queryForList("SELECT replies.message_id FROM replies " + - "INNER JOIN messages ON replies.message_id = messages.message_id " + - "LEFT JOIN messages_tags ON messages_tags.message_id = messages.message_id " + - "WHERE COALESCE(messages_tags.tag_id, 0) != 2 " + - "AND COALESCE(messages_tags.tag_id, 0) != 805 AND replies.ts > TIMESTAMPADD(HOUR, -2, CURRENT_TIMESTAMP) " + - "AND messages.popular=0 GROUP BY messages.message_id having COUNT(DISTINCT(replies.user_id)) > 5 " + - "UNION ALL SELECT favorites.message_id FROM favorites " + - "INNER JOIN messages ON messages.message_id = favorites.message_id " + - "LEFT JOIN messages_tags ON messages_tags.message_id = messages.message_id " + - "WHERE COALESCE(messages_tags.tag_id, 0) != 2 AND favorites.ts > TIMESTAMPADD(HOUR, -2, CURRENT_TIMESTAMP) " + - "AND messages.popular=0 GROUP BY messages.message_id HAVING COUNT(DISTINCT favorites.user_id) > 1;", Integer.class); - } - @Transactional - @Override - public void setLastReadComment(User user, Integer mid, Integer rid) { - jdbcTemplate.update("UPDATE subscr_messages SET last_read_rid=GREATEST(?, last_read_rid) WHERE message_id=? AND suser_id=?", - rid, mid, user.getUid()); - } - - @Override - public List<Integer> getUnread(User user) { - return jdbcTemplate.queryForList( - "select subscr_messages.message_id " + - "from subscr_messages inner join messages on subscr_messages.message_id=messages.message_id " + - "where subscr_messages.suser_id=? and " + - "messages.replies>subscr_messages.last_read_rid", - Integer.class, user.getUid()); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/MessengerServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/MessengerServiceImpl.java deleted file mode 100644 index 57101ffe8..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/MessengerServiceImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.juick.service; - -import com.juick.User; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Repository -public class MessengerServiceImpl extends BaseJdbcService implements MessengerService { - - @Transactional(readOnly = true) - @Override - public Integer getUserId(String senderId) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT id FROM users INNER JOIN messenger " + - "ON messenger.user_id = users.id WHERE messenger.sender_id=?", Integer.class, senderId); - - return list.isEmpty() ? 0 : list.get(0); - } - @Transactional(readOnly = true) - @Override - public Optional<String> getSenderId(User user) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT sender_id FROM messenger " + - "WHERE user_id=?", String.class, user.getUid()); - - return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); - } - - @Transactional - @Override - public boolean createMessengerUser(String senderId, String displayName) { - return getJdbcTemplate().update( - "INSERT INTO messenger(sender_id, display_name, loginhash) VALUES(?,?,?)", - senderId, displayName, UUID.randomUUID().toString()) > 0; - } - @Transactional(readOnly = true) - @Override - public String getDisplayName(String hash) { - try { - return getJdbcTemplate().queryForObject("SELECT display_name FROM messenger WHERE loginhash=?", String.class, hash); - } catch (EmptyResultDataAccessException e) { - return null; - } - } - @Transactional - @Override - public String getSignUpHash(final String senderId, final String username) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT loginhash FROM messenger WHERE sender_id = ? AND user_id IS NULL", - String.class, - senderId); - - if (list.isEmpty()) { - String hash = UUID.randomUUID().toString(); - getJdbcTemplate().update( - "INSERT INTO messenger(sender_id, loginhash, display_name) VALUES (?, ?, ?)", senderId, hash, username); - return hash; - } - return list.get(0); - } - @Transactional - @Override - public boolean linkMessengerUser(String hash, int uid) { - return getJdbcTemplate().update("UPDATE messenger SET user_id=?, loginhash=NULL WHERE loginhash=?", uid, hash) > 0; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java deleted file mode 100644 index b68e02361..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.User; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesService { - - @Transactional - @Override - public boolean createPM(final int uidFrom, final int uid_to, final String body) { - boolean ret = getJdbcTemplate().update( - "INSERT INTO pm(user_id, user_id_to, txt) VALUES (?, ?, ?)", - uidFrom, uid_to, body) > 0; - - if (ret) { - try { - getJdbcTemplate().update( - "INSERT INTO pm_streams(user_id, user_id_to, lastmessage, unread) VALUES (?, ?, NOW(), 1)", - uidFrom, uid_to); - } catch (DuplicateKeyException e) { - // ignore - } - } - return ret; - } - - @Transactional - @Override - public boolean addPMinRoster(final int uid, final String jid) { - return getJdbcTemplate().update( - "INSERT INTO pm_inroster(user_id, jid) VALUES (?, ?) ON DUPLICATE KEY UPDATE user_id=user_id", uid, jid) > 0; - } - - @Transactional - @Override - public boolean removePMinRoster(final int uid, final String jid) { - return getJdbcTemplate().update( - "DELETE FROM pm_inroster WHERE user_id = ? AND jid = ?", uid, jid) > 0; - } - - @Transactional - @Override - public boolean havePMinRoster(final int uid, final String jid) { - List<Integer> res = getJdbcTemplate().queryForList( - "SELECT 1 FROM pm_inroster WHERE user_id = ? AND jid = ?", - Integer.class, - uid, jid); - return res.size() > 0; - } - - @Transactional(readOnly = true) - @Override - public String getLastView(final int uidFrom, final int uidTo) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT lastview FROM pm_streams WHERE user_id = ? AND user_id_to = ?", - String.class, - uidFrom, uidTo); - - return list.isEmpty() ? - null : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public List<User> getPMLastConversationsUsers(final int uid, final int cnt) { - return getJdbcTemplate().query( - "SELECT pm_streams.user_id, users.nick, pm_streams.unread FROM pm_streams " - + "INNER JOIN users ON users.id = pm_streams.user_id " - + "WHERE pm_streams.user_id_to=? " - + "ORDER BY pm_streams.unread DESC, pm_streams.lastmessage DESC LIMIT ?", - (rs, rowNum) -> { - com.juick.User u = new com.juick.User(); - u.setUid(rs.getInt(1)); - u.setName(rs.getString(2)); - u.setUnreadCount(rs.getInt(3)); - return u; - }, - uid, cnt); - } - - @Transactional - @Override - public List<com.juick.Message> getPMMessages(final int uid, final int uidTo) { - SqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("uidTo", uidTo); - - List<com.juick.Message> msgs = getNamedParameterJdbcTemplate().query( - "SELECT pm.user_id, pm.txt, pm.ts, users.nick FROM pm INNER JOIN users ON users.id=pm.user_id WHERE (user_id = :uid AND user_id_to = :uidTo) " - + "OR (user_id_to = :uid AND user_id = :uidTo) ORDER BY ts DESC LIMIT 20", - sqlParameterSource, - (rs, rowNum) -> { - com.juick.Message msg = new com.juick.Message(); - int uuid = rs.getInt(1); - User user = new User(); - user.setUid(uuid); - user.setName(rs.getString(4)); - msg.setUser(user); - msg.setText(rs.getString(2)); - msg.setTimestamp(rs.getTimestamp(3).toInstant()); - return msg; - }); - - getNamedParameterJdbcTemplate().update( - "UPDATE pm_streams SET lastview = NOW(), unread = 0 WHERE user_id_to = :uid AND user_id = :uidTo", - sqlParameterSource); - - return msgs; - } - - @Transactional(readOnly = true) - @Override - public List<com.juick.Message> getLastPMInbox(final int uid) { - return getJdbcTemplate().query( - "SELECT pm.user_id, users.nick, pm.txt, pm.ts " + - "FROM pm INNER JOIN users ON pm.user_id=users.id WHERE pm.user_id_to=? ORDER BY pm.ts DESC LIMIT 20", - (rs, num) -> { - com.juick.Message msg = new com.juick.Message(); - msg.setUser(new User()); - msg.getUser().setUid(rs.getInt(1)); - msg.getUser().setName(rs.getString(2)); - msg.setText(rs.getString(3)); - msg.setTimestamp(rs.getTimestamp(4).toInstant()); - return msg; - }, - uid); - } - - @Transactional(readOnly = true) - @Override - public List<com.juick.Message> getLastPMSent(final int uid) { - return getJdbcTemplate().query( - "SELECT pm.user_id_to, users.nick, pm.txt, " + - "pm.ts FROM pm INNER JOIN users ON pm.user_id_to=users.id " + - "WHERE pm.user_id=? ORDER BY pm.ts DESC LIMIT 20", - (rs, num) -> { - com.juick.Message msg = new com.juick.Message(); - msg.setUser(new User()); - msg.getUser().setUid(rs.getInt(1)); - msg.getUser().setName(rs.getString(2)); - msg.setText(rs.getString(3)); - msg.setTimestamp(rs.getTimestamp(4).toInstant()); - return msg; - }, - uid); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/PrivacyQueriesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/PrivacyQueriesServiceImpl.java deleted file mode 100644 index 9f9cda1d1..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/PrivacyQueriesServiceImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.Tag; -import com.juick.User; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -@Transactional -public class PrivacyQueriesServiceImpl extends BaseJdbcService implements PrivacyQueriesService { - - @Override - public PrivacyResult blacklistUser(final User user, final User target) { - int result = getJdbcTemplate().update( - "DELETE FROM bl_users WHERE user_id = ? AND bl_user_id = ?", - user.getUid(), target.getUid()); - - if (result > 0) - return PrivacyResult.Removed; - - getJdbcTemplate().update( - "INSERT INTO bl_users(user_id, bl_user_id) VALUES (?, ?)", - user.getUid(), target.getUid()); - - return PrivacyResult.Added; - } - - @Override - public PrivacyResult blacklistTag(final User user, final Tag tag) { - int result = getJdbcTemplate().update( - "DELETE FROM bl_tags WHERE user_id = ? AND tag_id = ?", - user.getUid(), tag.TID); - - if (result > 0) - return PrivacyResult.Removed; - - getJdbcTemplate().update( - "INSERT INTO bl_tags(user_id, tag_id) VALUES (?, ?)", - user.getUid(), tag.TID); - - return PrivacyResult.Added; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/PushQueriesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/PushQueriesServiceImpl.java deleted file mode 100644 index 7f97956c0..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/PushQueriesServiceImpl.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import org.apache.commons.collections4.CollectionUtils; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import javax.inject.Inject; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class PushQueriesServiceImpl extends BaseJdbcService implements PushQueriesService { - - @Transactional(readOnly = true) - @Override - public List<String> getGCMRegID(final int uid) { - return getJdbcTemplate().queryForList( - "SELECT regid FROM android WHERE user_id=?", - String.class, - uid); - } - - @Transactional(readOnly = true) - @Override - public List<String> getGCMTokens(final Collection<Integer> uids) { - if (CollectionUtils.isEmpty(uids)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT regid FROM android INNER JOIN users ON (users.id = android.user_id) WHERE users.id IN (:ids)", - new MapSqlParameterSource("ids", uids), - String.class); - } - - @Transactional - @Override - public boolean addGCMToken(Integer uid, String token) { - return getJdbcTemplate().update("INSERT IGNORE INTO android(user_id,regid) VALUES (?, ?)", - uid, token) > 0; - } - - @Transactional - @Override - public boolean deleteGCMToken(String token) { - return getJdbcTemplate().update("DELETE FROM android WHERE regid=?", token) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getMPNSURL(final int uid) { - return getJdbcTemplate().queryForList( - "SELECT url FROM winphone WHERE user_id=?", - String.class, - uid); - } - - @Transactional(readOnly = true) - @Override - public List<String> getMPNSTokens(final Collection<Integer> uids) { - if (CollectionUtils.isEmpty(uids)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT url FROM winphone INNER JOIN users ON (users.id=winphone.user_id) WHERE users.id IN (:ids)", - new MapSqlParameterSource("ids", uids), - String.class); - } - - @Transactional - @Override - public boolean addMPNSToken(Integer uid, String token) { - return getJdbcTemplate().update("INSERT IGNORE INTO winphone(user_id,url) VALUES (?, ?)", - uid, token) > 0; - } - - @Transactional - @Override - public boolean deleteMPNSToken(String token) { - return getJdbcTemplate().update("DELETE FROM winphone WHERE url=?", token) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getAPNSToken(final int uid) { - return getJdbcTemplate().queryForList( - "SELECT token from ios WHERE user_id=?", - String.class, - uid); - } - - @Transactional - @Override - public boolean deleteAPNSToken(String token) { - return getJdbcTemplate().update("DELETE FROM ios WHERE token=?", token) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getAPNSTokens(final Collection<Integer> uids) { - if (CollectionUtils.isEmpty(uids)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT token FROM ios INNER JOIN users ON (users.id = ios.user_id) WHERE users.id IN (:ids)", - new MapSqlParameterSource("ids", uids), - String.class); - } - - @Transactional - @Override - public boolean addAPNSToken(Integer uid, String token) { - try { - return getJdbcTemplate().update("INSERT INTO ios(user_id,token) VALUES (?, ?)", - uid, token) > 0; - } catch (DuplicateKeyException e) { - return true; - } - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/ShowQueriesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/ShowQueriesServiceImpl.java deleted file mode 100644 index 0fba35f13..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/ShowQueriesServiceImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.User; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collections; -import java.util.List; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -@Transactional(readOnly = true) -public class ShowQueriesServiceImpl extends BaseJdbcService implements ShowQueriesService { - - @Override - public List<String> getRecommendedUsers(final User forUser) { - if (forUser == null) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT u.nick FROM subscr_users su1 INNER JOIN users u " + - "ON su1.user_id = u.id " + - "WHERE NOT EXISTS (SELECT 1 FROM subscr_users su2 WHERE su2.suser_id = :uid and su1.user_id = su2.user_id) " + - "AND EXISTS (SELECT 1 FROM subscr_users su3 WHERE su3.suser_id = :uid and su3.user_id = su1.suser_id ) " + - "AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.user_id = :uid and su1.user_id = b.bl_user_id) " + - "AND su1.user_id != :uid AND u.lastmessage > UNIX_TIMESTAMP() - 259200 " + - "GROUP BY su1.user_id ORDER BY count(*) DESC LIMIT 10", - new MapSqlParameterSource("uid", forUser.getUid()), - String.class); - } - - @Override - public List<String> getTopUsers() { - return getJdbcTemplate().query( - "SELECT users.nick,COUNT(subscr_users.suser_id) AS cnt " + - "FROM (subscr_users INNER JOIN users ON subscr_users.user_id=users.id) " + - "INNER JOIN useroptions ON users.id=useroptions.user_id " + - "WHERE useroptions.privacy_view>0 AND users.lastmessage > UNIX_TIMESTAMP() - 259200 " + - "AND users.id!=2 GROUP BY subscr_users.user_id ORDER BY cnt DESC LIMIT 10", - (rs, rowNum) -> rs.getString(1)); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/SphinxSearchService.java b/juick-server-jdbc/src/main/java/com/juick/service/SphinxSearchService.java deleted file mode 100644 index f102ab47d..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/SphinxSearchService.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * Created by aalexeev on 11/18/16. - */ - -@Repository -@Transactional(readOnly = true) -public class SphinxSearchService extends BaseJdbcService implements SearchService { - private static final int DEFAULT_MAX_RESULT = 20; - - private int maxResult = DEFAULT_MAX_RESULT; - - @Override - public List<Integer> searchInAllMessages(final String searchString, final int messageIdBefore) { - if (StringUtils.isBlank(searchString)) - return Collections.emptyList(); - - Map<String, String> sphinxQuery = new HashMap<>(); - sphinxQuery.put("limit", String.valueOf(maxResult)); - sphinxQuery.put("mode", "any"); - sphinxQuery.put("sort", "extended:@id desc"); - if (messageIdBefore > 0) { - sphinxQuery.put("maxid", String.valueOf(messageIdBefore - 1)); - } - - return getJdbcTemplate().queryForList( - String.format("SELECT id FROM search WHERE query = '%s;%s'", searchString, - sphinxQuery.entrySet().stream().map(Object::toString) - .collect(Collectors.joining(";"))), Integer.class); - } - - @Override - public List<Integer> searchByStringAndUser(final String searchString, final int userId, int messageIdBefore) { - if (StringUtils.isBlank(searchString)) - return Collections.emptyList(); - - Map<String, String> sphinxQuery = new HashMap<>(); - sphinxQuery.put("limit", String.valueOf(maxResult)); - sphinxQuery.put("mode", "any"); - sphinxQuery.put("sort", "extended:@id desc"); - if (messageIdBefore > 0) { - sphinxQuery.put("maxid", String.valueOf(messageIdBefore - 1)); - } - return getJdbcTemplate().queryForList( - String.format("SELECT id FROM search WHERE query = '%s;%s;filter=user_id,%d'", searchString, - sphinxQuery.entrySet().stream().map(Object::toString) - .collect(Collectors.joining(";")), userId), Integer.class); - } - - @Override - public void setMaxResult(int maxResult) { - if (maxResult <= 0) - throw new IllegalArgumentException("maxResult value (" + maxResult + ") must be greater then 0"); - - this.maxResult = maxResult; - } -}
\ No newline at end of file diff --git a/juick-server-jdbc/src/main/java/com/juick/service/SubscriptionServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/SubscriptionServiceImpl.java deleted file mode 100644 index b97fc0a45..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/SubscriptionServiceImpl.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.Message; -import com.juick.Tag; -import com.juick.User; -import com.juick.server.helpers.NotifyOpts; -import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.Assert; - -import javax.annotation.Nonnull; -import javax.inject.Inject; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class SubscriptionServiceImpl extends BaseJdbcService implements SubscriptionService { - @Inject - private UserService userService; - @Inject - private MessagesService messagesService; - @Inject - private TagService tagService; - - @Transactional(readOnly = true) - @Override - public List<String> getJIDSubscribedToUser(final int uid, final boolean friendsonly) { - return getNamedParameterJdbcTemplate().queryForList( - "SELECT jids.jid FROM subscr_users INNER JOIN jids " + - "ON (subscr_users.user_id = :uid AND subscr_users.suser_id = jids.user_id) WHERE jids.active = 1 " + - (friendsonly ? - " AND EXISTS (SELECT 1 FROM wl_users w WHERE w.user_id = :uid and jids.user_id = w.wl_user_id)" : StringUtils.EMPTY), - new MapSqlParameterSource("uid", uid), - String.class); - } - - @Transactional(readOnly = true) - @Override - public List<User> getSubscribedUsers(final int uid, final int mid) { - User author = messagesService.getMessageAuthor(mid); - - List<User> userids = userService.getUserReaders(uid); - List<Integer> tags = tagService.getMessageTagsIDs(mid); - List<String> tagsStr = tagService.getMessageTags(mid).stream().map(t -> t.getTag().getName()).collect(Collectors.toList()); - - Set<Integer> set = new HashSet<>(); - set.addAll( - userids.stream() - .map(User::getUid).filter(u -> Collections.disjoint(tagService.getUserBLTags(u), tagsStr)) - .collect(Collectors.toList())); - - - if (!tags.isEmpty()) { - List<Integer> tagUsers = getNamedParameterJdbcTemplate().queryForList( - "SELECT st.suser_id FROM subscr_tags st " + - "WHERE st.tag_id IN (:ids) AND st.suser_id != :uid " + - " AND NOT EXISTS (SELECT 1 FROM bl_users bu WHERE bu.bl_user_id = :authorUid and st.suser_id = bu.user_id)" + - " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN (:ids) and st.suser_id = bt.user_id)", - new MapSqlParameterSource() - .addValue("ids", tags) - .addValue("uid", uid) - .addValue("authorUid", author.getUid()), - Integer.class); - set.addAll(tagUsers); - } - return userService.getUsersByID(set); - } - @Override - public List<User> getUsersSubscribedToComments(@Nonnull final Message msg, @Nonnull final Message reply) { - return getUsersSubscribedToComments(msg, reply, false); - } - - @Transactional(readOnly = true) - @Override - public List<User> getUsersSubscribedToComments(@Nonnull final Message msg, @Nonnull final Message reply, - boolean blacklisted) { - List<Integer> userids = getJdbcTemplate().queryForList( - "SELECT suser_id FROM subscr_messages WHERE message_id=? AND suser_id!=?", - Integer.class, - msg.getMid(), reply.getUser().getUid()); - - if (!userids.isEmpty()) { - return userService.getUsersByID(userids.stream() - .filter(u -> blacklisted || !userService.isInBLAny(u, reply.getUser().getUid())) - .collect(Collectors.toList())); - } - return Collections.emptyList(); - } - - @Transactional(readOnly = true) - @Override - public List<User> getUsersSubscribedToUserRecommendations(final int uid, final int mid, final int muid) { - List<Integer> tags = tagService.getMessageTagsIDs(mid); - - String query = "SELECT s.suser_id FROM subscr_users s WHERE s.user_id = :uid " + - " AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.bl_user_id = :muid and b.user_id = s.user_id) " + - " AND NOT EXISTS (SELECT 1 FROM subscr_users s1 WHERE s1.user_id = :muid AND s.user_id = s1.suser_id) " + - " AND NOT EXISTS (SELECT 1 FROM subscr_messages sm WHERE sm.message_id = :mid AND s.user_id = sm.suser_id) " + - " AND NOT EXISTS (SELECT 1 FROM favorites WHERE favorites.message_id = :mid AND favorites.user_id = s.user_id) " + - " AND s.user_id NOT IN (SELECT s2.suser_id FROM subscr_users s2 " + - " INNER JOIN favorites f ON (f.message_id = :mid AND s2.user_id = f.user_id AND f.user_id != :uid))"; - - MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("muid", muid) - .addValue("mid", mid); - - if (!tags.isEmpty()) { - sqlParameterSource.addValue("ids", tags); - query += " AND NOT EXISTS (SELECT 1 FROM subscr_tags st WHERE st.tag_id IN (:ids) AND s.user_id = st.suser_id) " + - " AND NOT EXISTS (SELECT 1 FROM bl_tags b WHERE b.tag_id IN (:ids) AND s.user_id = b.user_id)"; - } - - List<Integer> userids = getNamedParameterJdbcTemplate().queryForList( - query, sqlParameterSource, Integer.class); - - return userService.getUsersByID(userids); - } - - @Transactional - @Override - public boolean subscribeMessage(final Message message, final User user) { - try { - boolean result = getJdbcTemplate().update( - "INSERT INTO subscr_messages(suser_id, message_id) VALUES (?, ?)", user.getUid(), message.getMid()) == 1; - messagesService.setLastReadComment(user, message.getMid(), message.getReplies()); - return result; - } catch (DuplicateKeyException e) { - return true; - } - } - - @Transactional - @Override - public boolean unSubscribeMessage(final int mid, final int vuid) { - return getJdbcTemplate().update( - "DELETE FROM subscr_messages WHERE message_id=? AND suser_id=?", mid, vuid) > 0; - } - - @Transactional - @Override - public boolean subscribeUser(final User user, final User toUser) { - try { - return getJdbcTemplate().update( - "INSERT INTO subscr_users(user_id,suser_id) VALUES (?,?)", toUser.getUid(), user.getUid()) == 1; - } catch (DuplicateKeyException e) { - return true; - } - } - - @Transactional - @Override - public boolean unSubscribeUser(final User user, final User fromUser) { - return getJdbcTemplate().update( - "DELETE FROM subscr_users WHERE suser_id=? AND user_id=?", user.getUid(), fromUser.getUid()) > 0; - } - - @Transactional - @Override - public boolean subscribeTag(final User user, final Tag toTag) { - try { - - return getJdbcTemplate().update( - "INSERT INTO subscr_tags(tag_id,suser_id) VALUES (?,?)", toTag.TID, user.getUid()) == 1; - } catch (DuplicateKeyException e) { - return true; - } - } - - @Transactional - @Override - public boolean unSubscribeTag(final User user, final Tag toTag) { - return getJdbcTemplate().update( - "DELETE FROM subscr_tags WHERE tag_id=? AND suser_id=?", toTag.TID, user.getUid()) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getSubscribedTags(User user) { - return getJdbcTemplate().queryForList("SELECT tags.name FROM subscr_tags INNER JOIN tags " + - "ON(tags.tag_id = subscr_tags.tag_id) " + - "WHERE subscr_tags.suser_id=? ORDER BY tags.name", String.class, user.getUid()); - } - - @Transactional(readOnly = true) - @Override - public NotifyOpts getNotifyOptions(final User user) { - List<NotifyOpts> list = getJdbcTemplate().query( - "SELECT jnotify,subscr_notify,recommendations FROM useroptions WHERE user_id=?", - (rs, num) -> { - NotifyOpts options = new NotifyOpts(); - options.setRepliesEnabled(rs.getInt(1) > 0); - options.setSubscriptionsEnabled(rs.getInt(2) > 0); - options.setRecommendationsEnabled(rs.getInt(3) > 0); - return options; - }, - user.getUid()); - - return list.isEmpty() ? - new NotifyOpts() : list.get(0); - } - - @Transactional - @Override - public boolean setNotifyOptions(final User user, final NotifyOpts options) { - int jnotify = getJdbcTemplate().update( - "UPDATE useroptions SET jnotify=? WHERE user_id=?", - options.isRepliesEnabled() ? 1 : 0, - user.getUid()); - - int subscr_notify = getJdbcTemplate().update( - "UPDATE useroptions SET subscr_notify=? WHERE user_id=?", - options.isSubscriptionsEnabled() ? 1 : 0, - user.getUid()); - - int recommendations = getJdbcTemplate().update( - "UPDATE useroptions SET recommendations=? WHERE user_id=?", - options.isRecommendationsEnabled() ? 1 : 0, - user.getUid()); - - return jnotify > 0 && subscr_notify > 0 && recommendations > 0; - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/TagServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/TagServiceImpl.java deleted file mode 100644 index 524ad32d2..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/TagServiceImpl.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.Tag; -import com.juick.User; -import com.juick.server.helpers.TagStats; -import com.juick.util.StreamUtils; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class TagServiceImpl extends BaseJdbcService implements TagService { - - @Transactional(readOnly = true) - @Override - public com.juick.Tag getTag(final int tid) { - List<Tag> list = getJdbcTemplate().query( - "SELECT synonym_id,name FROM tags WHERE tag_id=?", - (rs, num) -> { - Tag ret = new Tag(rs.getString(2)); - ret.TID = tid; - ret.SynonymID = rs.getInt(1); - return ret; - }, - tid); - - return list.isEmpty() ? - null : list.get(0); - } - - @Transactional - @Override - public com.juick.Tag getTag(final String tag, final boolean autoCreate) { - if (StringUtils.isBlank(tag)) - return null; - - List<Tag> list = getJdbcTemplate().query( - "SELECT tag_id, synonym_id, name FROM tags WHERE name = ?", - (rs, rowNum) -> { - Tag ret1 = new Tag(rs.getString(3)); - ret1.TID = rs.getInt(1); - ret1.SynonymID = rs.getInt(2); - return ret1; - }, - tag); - - Tag ret = list.isEmpty() ? - null : list.get(0); - - if (ret == null && autoCreate) { - ret = new com.juick.Tag(tag); - ret.TID = createTag(tag); - } - - return ret; - } - - @Override - public List<Tag> getTags(Stream<String> tags, final boolean autoCreate) { - return tags.filter(StringUtils::isNotBlank).map(tag -> getTag(tag, autoCreate)).filter(Objects::nonNull).distinct() - .collect(Collectors.toList()); - } - - @Transactional(readOnly = true) - @Override - public boolean getTagNoIndex(final int tagId) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT noindex FROM tags WHERE tag_id=?", Integer.class, tagId); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional - @Override - public int createTag(final String name) { - KeyHolder holder = new GeneratedKeyHolder(); - getJdbcTemplate().update( - con -> { - PreparedStatement stmt = con.prepareStatement( - "INSERT INTO tags(name) VALUES (?)", - Statement.RETURN_GENERATED_KEYS); - stmt.setString(1, name); - return stmt; - }, - holder); - - return holder.getKey().intValue(); - } - - private class TagStatsMapper implements RowMapper<TagStats> { - - @Override - public TagStats mapRow(ResultSet rs, int rowNum) throws SQLException { - Tag t = new Tag(rs.getString(1)); - TagStats s = new TagStats(); - s.setTag(t); - s.setUsageCount(rs.getInt(2)); - return s; - } - } - - @Transactional(readOnly = true) - @Override - public List<TagStats> getUserTagStats(final int uid) { - return getJdbcTemplate().query( - "SELECT tags.name,COUNT(messages.message_id) " + - "FROM (messages INNER JOIN messages_tags ON (messages.user_id=? " + - "AND messages.message_id=messages_tags.message_id)) " + - "INNER JOIN tags ON messages_tags.tag_id=tags.tag_id GROUP BY tags.tag_id ORDER BY tags.name ASC", - new TagStatsMapper(), - uid); - } - - @Transactional(readOnly = true) - @Override - public List<String> getUserBLTags(final int uid) { - return getJdbcTemplate().queryForList( - "SELECT tags.name FROM tags INNER JOIN bl_tags " + - "ON (bl_tags.user_id = ? AND bl_tags.tag_id = tags.tag_id) ORDER BY tags.name", - String.class, uid); - } - - @Transactional(readOnly = true) - @Override - public List<String> getPopularTags() { - return getJdbcTemplate().queryForList( - "select name from tags where noindex=0 order by stat_messages desc limit 20", String.class); - } - - @Transactional(readOnly = true) - @Override - public List<TagStats> getTagStats() { - return getJdbcTemplate().query( - "SELECT tags.name,COUNT(DISTINCT messages.user_id) AS cnt " + - "FROM (messages INNER JOIN messages_tags ON (messages.ts>TIMESTAMPADD(DAY,-3,NOW()) " + - "AND messages.message_id=messages_tags.message_id)) " + - "INNER JOIN tags ON messages_tags.tag_id=tags.tag_id " + - "WHERE tags.tag_id NOT IN (SELECT tag_id FROM tags_ignore) " + - "GROUP BY tags.tag_id ORDER BY cnt DESC LIMIT 20", new TagStatsMapper()); - } - - @Transactional - @Override - public List<Tag> updateTags(final int mid, final Collection<Tag> newTags) { - List<Tag> currentTags = getMessageTags(mid).stream() - .map(TagStats::getTag).collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(newTags)) - return currentTags; - - List<Integer> idsForDelete = newTags.stream() - .filter(currentTags::contains) - .map(tag -> tag.TID) - .collect(Collectors.toList()); - if (newTags.size() - idsForDelete.size() >= 5) { - return currentTags; - } - - if (!idsForDelete.isEmpty()) - getNamedParameterJdbcTemplate().update( - "DELETE FROM messages_tags WHERE message_id = :mid AND tag_id in (:ids)", - new MapSqlParameterSource().addValue("ids", idsForDelete).addValue("mid", mid)); - - newTags.stream().filter(t -> !currentTags.contains(t)) - .forEach(t -> getJdbcTemplate().update("INSERT INTO messages_tags(message_id,tag_id) VALUES (?,?)", mid, t.TID)); - - List<Tag> result = getMessageTags(mid).stream() - .map(TagStats::getTag).collect(Collectors.toList()); - jdbcTemplate.update("UPDATE messages_txt SET tags=? WHERE message_id=?", result.stream() - .map(Tag::getName).collect(Collectors.joining(" ")), mid); - return result; - } - - @Override - public List<Tag> fromString(final String txt) { - String firstLine = txt.split("\\n", 2)[0]; - return StreamUtils.takeWhile(Arrays.stream(firstLine.split("\\ ")), - t -> !t.equals("*") && t.startsWith("*")) - .map(t -> getTag(t.substring(1), true)) - .collect(Collectors.toList()); - } - - @Transactional(readOnly = true) - @Override - public List<TagStats> getMessageTags(final int mid) { - return getJdbcTemplate().query( - "SELECT tags.tag_id,synonym_id,name,stat_messages FROM tags " + - "INNER JOIN messages_tags ON (messages_tags.message_id = ? AND messages_tags.tag_id = tags.tag_id)", - (rs, num) -> { - com.juick.Tag t = new com.juick.Tag(rs.getString(3)); - t.TID = rs.getInt(1); - t.SynonymID = rs.getInt(2); - TagStats s = new TagStats(); - s.setTag(t); - s.setUsageCount(rs.getInt(4)); - return s; - }, mid); - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getMessageTagsIDs(final int mid) { - return getJdbcTemplate().queryForList( - "SELECT tag_id FROM messages_tags WHERE message_id = ?", - Integer.class, mid); - } - - @Override - public boolean blacklistTag(User user, Tag tag) { - int rowcount = getNamedParameterJdbcTemplate().update("DELETE FROM bl_tags WHERE tag_id = :tid AND user_id = :uid", - new MapSqlParameterSource().addValue("tid", tag.TID).addValue("uid", user.getUid())); - return rowcount <= 0 && getNamedParameterJdbcTemplate() - .update("INSERT INTO bl_tags(user_id, tag_id) VALUES(:uid,:tid)", - new MapSqlParameterSource().addValue("tid", tag.TID) - .addValue("uid", user.getUid())) > 0; - } - - @Transactional(readOnly = true) - @Override - public boolean isInBL(User user, Tag tag) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM bl_tags WHERE user_id = ? AND tag_id = ?", - Integer.class, user.getUid(), tag.TID); - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public boolean isSubscribed(User user, Tag tag) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM subscr_tags WHERE suser_id = ? AND tag_id = ?", - Integer.class, user.getUid(), tag.TID); - return !list.isEmpty() && list.get(0) == 1; - } - -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/TelegramServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/TelegramServiceImpl.java deleted file mode 100644 index 4e37bfac9..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/TelegramServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.User; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * Created by vt on 24/11/2016. - */ -@Repository -public class TelegramServiceImpl extends BaseJdbcService implements TelegramService { - - @Transactional - @Override - public boolean addChat(final Long id) { - try { - return getJdbcTemplate().update("INSERT INTO telegram_chats(chat_id) VALUES(?)", id) > 0; - } catch (DuplicateKeyException e) { - return true; - } - } - - @Transactional - @Override - public boolean deleteChat(Long id) { - return getJdbcTemplate().update("DELETE FROM telegram_chats WHERE chat_id=?", id) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<Long> getChats() { - return getJdbcTemplate().queryForList("SELECT chat_id FROM telegram_chats", Long.class); - } - - @Transactional(readOnly = true) - @Override - public int getUser(final long tgId) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT id FROM users INNER JOIN telegram " + - "ON telegram.user_id = users.id WHERE telegram.tg_id=?", Integer.class, tgId); - - return list.isEmpty() ? 0 : list.get(0); - } - - @Transactional - @Override - public boolean createTelegramUser(final long tgID, final String tgName) { - return getJdbcTemplate().update( - "INSERT INTO telegram(tg_id, tg_name, loginhash) VALUES(?,?,?)", - tgID, tgName, UUID.randomUUID().toString()) > 0; - } - - @Transactional - @Override - public boolean deleteTelegramUser(Integer uid) { - return getJdbcTemplate().update("DELETE FROM telegram WHERE user_id=?", uid) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<Long> getTelegramIdentifiers(List<User> users) { - List<Integer> uids = users.stream().map(User::getUid).collect(Collectors.toList()); - if (uids.isEmpty()) { - return Collections.emptyList(); - } - return getNamedParameterJdbcTemplate().queryForList("" + - "SELECT tg_id FROM telegram WHERE user_id IN(:uids)", new MapSqlParameterSource() - .addValue("uids", uids), Long.class); - } -} diff --git a/juick-server-jdbc/src/main/java/com/juick/service/UserServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/UserServiceImpl.java deleted file mode 100644 index a0a07fb35..000000000 --- a/juick-server-jdbc/src/main/java/com/juick/service/UserServiceImpl.java +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package com.juick.service; - -import com.juick.User; -import com.juick.server.helpers.AnonymousUser; -import com.juick.server.helpers.Auth; -import com.juick.server.helpers.UserInfo; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DuplicateKeyException; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.*; - -/** - * Created by aalexeev on 11/13/16. - */ -@Repository -public class UserServiceImpl extends BaseJdbcService implements UserService { - - private class UserMapper implements RowMapper<User> { - @Override - public User mapRow(ResultSet rs, int rowNum) throws SQLException { - User user = new User(); - - user.setUid(rs.getInt(1)); - user.setName(rs.getString(2)); - user.setBanned(rs.getBoolean(3)); - user.setLang(rs.getString(4)); - - return user; - } - } - - @Transactional - @Override - public String getSignUpHashByJID(final String jid) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT loginhash FROM jids WHERE jid = ? AND user_id IS NULL", String.class, jid); - - if (list.isEmpty()) { - String hash = UUID.randomUUID().toString(); - getJdbcTemplate().update("INSERT INTO jids(jid, loginhash) VALUES (?, ?)", jid, hash); - return hash; - } - return list.get(0); - } - - @Transactional - @Override - public String getSignUpHashByTelegramID(final Long telegramId, final String username) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT loginhash FROM telegram WHERE tg_id = ? AND user_id IS NULL", - String.class, - telegramId); - - if (list.isEmpty()) { - String hash = UUID.randomUUID().toString(); - getJdbcTemplate().update( - "INSERT INTO telegram(tg_id, loginhash, tg_name) VALUES (?, ?, ?)", telegramId, hash, username); - return hash; - } - return list.get(0); - } - - @Transactional - @Override - public int createUser(final String username, final String password) { - KeyHolder holder = new GeneratedKeyHolder(); - try { - getJdbcTemplate().update( - con -> { - PreparedStatement stmt = con.prepareStatement( - "INSERT INTO users(nick,passw) VALUES (?,?)", - Statement.RETURN_GENERATED_KEYS); - stmt.setString(1, username); - stmt.setString(2, password); - return stmt; - }, - holder); - } catch (DuplicateKeyException e) { - return -1; - } - - int uid = holder.getKey().intValue(); - - getJdbcTemplate().update("INSERT INTO useroptions(user_id) VALUES (?)", uid); - getJdbcTemplate().update("INSERT INTO subscr_users(user_id, suser_id) VALUES (2, ?)", uid); - - return uid; - } - - @Transactional(readOnly = true) - @Override - public Optional<User> getUserByUID(final int uid) { - List<User> list = getJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE id = ?", new UserMapper(), uid); - - return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); - } - - @Transactional(readOnly = true) - @Override - public User getUserByName(final String username) { - if (StringUtils.isNotBlank(username)) { - List<User> list = getJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE nick = ?", new UserMapper(), username); - - if (!list.isEmpty()) - return list.get(0); - } - // TODO: @NonNullable ? - return AnonymousUser.INSTANCE; - } - - @Override - // No need marks with @Transactional annotation - public User getFullyUserByName(final String username) { - if (StringUtils.isNotBlank(username)) { - List<User> list = getFullyUsersByNames(Collections.singletonList(username)); - if (!list.isEmpty()) - return list.get(0); - } - return null; - } - - @Override - @Transactional(readOnly = true) - public User getUserByEmail(String email) { - if (StringUtils.isNotBlank(email)) { - List<User> list = getJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE id = (SELECT DISTINCT user_id FROM emails WHERE email = ?)", - new UserMapper(), - email); - - if (!list.isEmpty()) - return list.get(0); - } - return AnonymousUser.INSTANCE; - } - - @Transactional(readOnly = true) - @Override - public List<User> getFullyUsersByNames(final Collection<String> usernames) { - if (CollectionUtils.isEmpty(usernames)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().query( - "SELECT id, nick, passw, lang, banned FROM users WHERE nick in (:names)", - new MapSqlParameterSource("names", usernames), - (rs, rowNum) -> { - User user = new User(); - - user.setUid(rs.getInt(1)); - user.setName(rs.getString(2)); - user.setCredentials(rs.getString(3)); - user.setLang(rs.getString(4)); - user.setBanned(rs.getBoolean(5)); - - return user; - }); - } - - @Transactional(readOnly = true) - @Override - public User getUserByJID(final String jid) { - User result = null; - - if (StringUtils.isNotBlank(jid)) { - List<User> list = getJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE id = (SELECT user_id FROM jids WHERE jid = ?)", - new UserMapper(), - jid); - - if (!list.isEmpty()) - result = list.get(0); - } - return result; - } - - @Transactional(readOnly = true) - @Override - public List<User> getUsersByName(final Collection<String> unames) { - if (CollectionUtils.isEmpty(unames)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE nick IN (:unames)", - new MapSqlParameterSource("unames", unames), - new UserMapper()); - } - - @Transactional(readOnly = true) - @Override - public List<User> getUsersByID(final Collection<Integer> uids) { - if (CollectionUtils.isEmpty(uids)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().query( - "SELECT id, nick, banned, lang FROM users WHERE id IN (:ids)", - new MapSqlParameterSource("ids", uids), - new UserMapper()); - } - - @Transactional(readOnly = true) - @Override - public List<String> getJIDsbyUID(final int uid) { - return getJdbcTemplate().queryForList("SELECT jid FROM jids WHERE user_id = ? AND active = 1", String.class, uid); - } - - @Transactional(readOnly = true) - @Override - public int getUIDbyJID(final String jid) { - if (StringUtils.isNotBlank(jid)) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT user_id FROM jids WHERE jid = ?", Integer.class, jid); - - if (!list.isEmpty()) - return list.get(0); - } - return 0; - } - - @Transactional(readOnly = true) - @Override - public int getUIDbyName(final String uname) { - if (StringUtils.isNotBlank(uname)) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT id FROM users WHERE nick = ?", Integer.class, uname); - - if (!list.isEmpty()) - return list.get(0); - } - return 0; - } - - @Transactional(readOnly = true) - @Override - public int getUIDbyHash(final String hash) { - if (StringUtils.isNotBlank(hash)) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT user_id FROM logins WHERE hash = ?", Integer.class, hash); - - if (!list.isEmpty()) - return list.get(0); - } - return 0; - } - - @Transactional(readOnly = true) - @Override - public com.juick.User getUserByHash(final String hash) { - if (StringUtils.isNotBlank(hash)) { - List<User> list = getJdbcTemplate().query( - "SELECT logins.user_id, users.nick, users.banned, users.lang FROM logins " + - "INNER JOIN users ON logins.user_id = users.id WHERE logins.hash = ?", - new UserMapper(), - hash); - - if (!list.isEmpty()) { - User user = list.get(0); - user.setAuthHash(hash); - return user; - } - } - return AnonymousUser.INSTANCE; - } - - @Transactional - @Override - public String getHashByUID(final int uid) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT hash FROM logins WHERE user_id = ?", String.class, uid); - - if (list.isEmpty()) { - String hash = RandomStringUtils.randomAlphanumeric(16).toUpperCase(); - getJdbcTemplate().update("INSERT INTO logins(user_id, hash) VALUES (?, ?)", uid, hash); - return hash; - } - return list.get(0); - } - - @Override - public int getUIDByHttpAuth(String auth) { - if (auth != null && auth.length() > 8 && auth.startsWith("Basic ")) { - Base64.Decoder dec = Base64.getDecoder(); - String loginpassw[] = new String(dec.decode(auth.substring(6))).split(":", 2); - if (loginpassw.length == 2 && loginpassw[0].length() > 1 && loginpassw[0].length() < 16 && loginpassw[0].matches("[a-zA-Z0-9\\-]+") && !loginpassw[1].isEmpty()) { - return checkPassword(loginpassw[0], loginpassw[1]); - } - } - return 0; - } - - @Transactional(readOnly = true) - @Override - public int checkPassword(final String username, final String password) { - if (StringUtils.isNotBlank(username)) { - List<User> list = getJdbcTemplate().query( - "SELECT id, nick, banned, passw FROM users WHERE nick = ?", - (rs, rowNum) -> { - User user = new User(); - user.setUid(rs.getInt(1)); - user.setName(rs.getString(2)); - user.setBanned(rs.getBoolean(3)); - user.setCredentials(rs.getString(4)); - return user; - }, - username); - - if (!list.isEmpty()) { - User user = list.get(0); - if (Objects.equals(password, user.getCredentials())) - return user.getUid(); - } - } - return -1; - } - - @Transactional - @Override - public boolean updatePassword(final User user, final String newPassword) { - return user != null && - user.getUid() > 0 && - getJdbcTemplate().update("UPDATE users SET passw = ? WHERE id = ?", newPassword, user.getUid()) > 0; - } - - @Transactional(readOnly = true) - @Override - public int getUserOptionInt(final int uid, final String option, final int defaultValue) { - if (StringUtils.isBlank(option)) - return defaultValue; - - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT " + option + " FROM useroptions WHERE user_id = ?", Integer.class, uid); - - return list.isEmpty() ? defaultValue : list.get(0); - } - - @Transactional - @Override - public int setUserOptionInt(final int uid, final String option, final int value) { - if (StringUtils.isBlank(option)) - return 0; - - return getJdbcTemplate().update("UPDATE useroptions SET " + option + "= ? WHERE user_id = ?", value, uid); - } - - @Transactional(readOnly = true) - @Override - public UserInfo getUserInfo(final User user) { - List<UserInfo> list = getJdbcTemplate().query( - "SELECT fullname, country, url, descr FROM usersinfo WHERE user_id = ?", - ((rs, rowNum) -> { - UserInfo info = new UserInfo(); - info.setFullName(rs.getString(1)); - info.setCountry(rs.getString(2)); - info.setUrl(rs.getString(3)); - info.setDescription(rs.getString(4)); - return info; - }), - user.getUid()); - - return list.isEmpty() ? new UserInfo() : list.get(0); - } - - @Transactional - @Override - public boolean updateUserInfo(final User user, final UserInfo info) { - return getJdbcTemplate().update( - "INSERT INTO usersinfo(user_id, fullname, country, url, descr) VALUES (?, ?, ?, ?, ?) " + - "ON DUPLICATE KEY UPDATE fullname = ?, country = ?, url = ?, descr = ?", - user.getUid(), - info.getFullName(), - info.getCountry(), - info.getUrl(), - info.getDescription(), - info.getFullName(), - info.getCountry(), - info.getUrl(), - info.getDescription()) > 0; - } - - @Transactional(readOnly = true) - @Override - public boolean getCanMedia(final int uid) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT users.lastphoto - UNIX_TIMESTAMP() FROM users WHERE id = ?", - Integer.class, - uid); - - return !list.isEmpty() && list.get(0) < 3600; - } - - @Transactional(readOnly = true) - @Override - public boolean isInWL(final int uid, final int check) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM wl_users WHERE user_id = ? AND wl_user_id = ?", - Integer.class, uid, check); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public boolean isInBL(final int uid, final int check) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM bl_users WHERE user_id = ? AND bl_user_id = ?", Integer.class, uid, check); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public boolean isInBLAny(final int uid, final int uid2) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM bl_users WHERE (user_id = ? AND bl_user_id = ?) " - + "OR (user_id = ? AND bl_user_id = ?)", - new Object[]{uid, uid2, uid2, uid}, - Integer.class); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public List<Integer> checkBL(final int visitor, final Collection<Integer> uids) { - if (CollectionUtils.isEmpty(uids)) - return Collections.emptyList(); - - return getNamedParameterJdbcTemplate().queryForList( - "SELECT user_id FROM bl_users WHERE bl_user_id = :visitor and user_id IN (:ids)", - new MapSqlParameterSource() - .addValue("visitor", visitor) - .addValue("ids", uids), - Integer.class); - } - - @Transactional(readOnly = true) - @Override - public boolean isSubscribed(final int uid, final int check) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT 1 FROM subscr_users WHERE suser_id = ? AND user_id = ?", - Integer.class, uid, check); - - return !list.isEmpty() && list.get(0) == 1; - } - - @Transactional(readOnly = true) - @Override - public List<Integer> getUserRead(final int uid) { - return getJdbcTemplate().queryForList( - "SELECT user_id FROM subscr_users WHERE suser_id=?", Integer.class, uid); - } - - @Transactional(readOnly = true) - @Override - public List<com.juick.User> getUserReadLeastPopular(final int uid, final int cnt) { - return getJdbcTemplate().query( - "SELECT users.id,users.nick FROM (subscr_users " + - "INNER JOIN users_subscr ON (subscr_users.suser_id=? " + - "AND subscr_users.user_id=users_subscr.user_id)) INNER JOIN users " + - "ON subscr_users.user_id=users.id ORDER BY cnt LIMIT ?", - (rs, num) -> { - com.juick.User u = new com.juick.User(); - u.setUid(rs.getInt(1)); - u.setName(rs.getString(2)); - return u; - }, - uid, - cnt); - } - - @Transactional(readOnly = true) - @Override - public List<User> getUserReaders(final int uid) { - return getJdbcTemplate().query( - "SELECT users.id, users.nick FROM subscr_users " + - "INNER JOIN users ON subscr_users.suser_id=users.id " + - "WHERE subscr_users.user_id=? ORDER BY users.nick", - (rs, num) -> { - com.juick.User u = new com.juick.User(); - u.setUid(rs.getInt(1)); - u.setName(rs.getString(2)); - return u; - }, - uid); - } - - @Transactional(readOnly = true) - @Override - public List<User> getUserFriends(final int uid) { - return getJdbcTemplate().query( - "SELECT users.id,users.nick FROM subscr_users " + - "INNER JOIN users ON subscr_users.user_id=users.id " + - "WHERE subscr_users.suser_id=? AND users.id!=? " + - "ORDER BY users.nick", - (rs, num) -> { - com.juick.User u = new com.juick.User(); - u.setUid(rs.getInt(1)); - u.setName(rs.getString(2)); - return u; - }, - uid, - uid); - } - - @Transactional(readOnly = true) - @Override - public List<com.juick.User> getUserBLUsers(final int uid) { - return getJdbcTemplate().query("SELECT users.id,users.nick FROM users INNER JOIN bl_users " + - "ON(bl_users.bl_user_id=users.id) WHERE bl_users.user_id=? ORDER BY users.nick", - (rs, num) -> { - com.juick.User u = new com.juick.User(); - u.setUid(rs.getInt(1)); - u.setName(rs.getString(2)); - return u; - }, uid); - } - - @Transactional - @Override - public boolean linkTwitterAccount( - final User user, final String accessToken, final String accessTokenSecret, final String screenName) { - if (getJdbcTemplate().update("INSERT INTO twitter(user_id,access_token,access_token_secret,uname) " + - "VALUES (?,?,?,?)" + - " ON DUPLICATE KEY UPDATE access_token=?,access_token_secret=?,uname=?", - user.getUid(), accessToken, accessTokenSecret, screenName, accessToken, accessTokenSecret, screenName) > 0) { - return getJdbcTemplate().update("INSERT INTO subscr_users(user_id,suser_id,jid) " + - "VALUES (?,1741,'juick\\@twitter.juick.com')", user.getUid()) > 0; - } - return false; - - } - - @Transactional(readOnly = true) - @Override - public int getStatsIRead(final int uid) { - List<Integer> list = getJdbcTemplate().queryForList( - "SELECT COUNT(*) FROM subscr_users WHERE suser_id = ?", Integer.class, uid); - return list.isEmpty() ? 0 : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public int getStatsMyReaders(final int uid) { - List<Integer> list = getJdbcTemplate().queryForList("SELECT COUNT(*) FROM subscr_users WHERE user_id = ?", Integer.class, uid); - return list.isEmpty() ? 0 : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public int getStatsMessages(final int uid) { - List<Integer> list = getJdbcTemplate().queryForList("SELECT COUNT(*) FROM messages WHERE user_id = ?", Integer.class, uid); - return list.isEmpty() ? 0 : list.get(0); - } - - @Transactional(readOnly = true) - @Override - public int getStatsReplies(final int uid) { - List<Integer> list = getJdbcTemplate().queryForList("SELECT COUNT(*) FROM replies WHERE user_id = ?", Integer.class, uid); - return list.isEmpty() ? 0 : list.get(0); - } - - @Transactional - @Override - public boolean setActiveStatusForJID(final String JID, final UserService.ActiveStatus jidStatus) { - User user = getUserByJID(JID); - if (user != null) { - int newStatus = jidStatus == UserService.ActiveStatus.Active ? 1 : 0; - return getJdbcTemplate().update( - "UPDATE jids SET active = ? WHERE user_id = ? AND jid = ?", - newStatus, user.getUid(), JID) >= 0; - } - return false; - } - - @Transactional(readOnly = true) - @Override - public List<String> getAllJIDs(final User user) { - return getJdbcTemplate().queryForList( - "SELECT jid FROM jids WHERE user_id=?", String.class, user.getUid()); - } - - @Transactional(readOnly = true) - @Override - public List<Auth> getAuthCodes(final User user) { - return getJdbcTemplate().query( - "SELECT account,authcode FROM auth WHERE user_id=? AND protocol='xmpp'", - (rs, num) -> new Auth(rs.getString(1), rs.getString(2)), - user.getUid()); - } - - @Transactional(readOnly = true) - @Override - public List<String> getEmails(final User user) { - return getJdbcTemplate().queryForList("SELECT email FROM emails WHERE user_id=?", String.class, user.getUid()); - } - - @Transactional(readOnly = true) - @Override - public String getEmailHash(final User user) { - List<String> list = getJdbcTemplate().queryForList( - "SELECT hash FROM mail WHERE user_id = ?", - String.class, - user.getUid()); - return list.isEmpty() ? StringUtils.EMPTY : list.get(0) + "@mail.juick.com"; - } - - @Transactional - @Override - public int deleteLoginForUser(final String name) { - if (StringUtils.isBlank(name)) - return 0; - - return getJdbcTemplate().update( - "delete from logins where user_id in (select id from users where nick = ?)", name); - } - - @Transactional - @Override - public int setLoginForUser(final int uid, final String loginHash) { - if (StringUtils.isEmpty(loginHash)) - return 0; - - return getNamedParameterJdbcTemplate().update( - "INSERT INTO logins (user_id, hash) VALUES(:uid, :hash) ON DUPLICATE KEY UPDATE hash = :hash", - new MapSqlParameterSource() - .addValue("hash", loginHash) - .addValue("uid", uid)); - } - - @Transactional - @Override - public void logout(int uid) { - getJdbcTemplate().update("DELETE FROM logins WHERE user_id=?", uid); - } - - @Transactional - @Override - public boolean deleteJID(int uid, String jid) { - return getNamedParameterJdbcTemplate().update("DELETE FROM jids " + - "WHERE (SELECT COUNT(*) cnt FROM (select user_id, jid FROM jids j) c WHERE user_id=:uid) > 1 " + - "AND user_id=:uid AND jid=:jid", - new MapSqlParameterSource() - .addValue("uid", uid) - .addValue("jid", jid)) > 0; - } - - @Transactional - @Override - public boolean unauthJID(int uid, String jid) { - return getJdbcTemplate() - .update("DELETE FROM auth WHERE user_id=? AND protocol='xmpp' AND account=?", uid, jid) > 0; - } - - @Transactional(readOnly = true) - @Override - public List<String> getActiveJIDs() { - return getJdbcTemplate().queryForList("SELECT jid FROM jids WHERE active=1 AND loginhash IS NULL", String.class); - } -} |