0%

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.jooq.Configuration;
import org.jooq.conf.MappedSchema;
import org.jooq.conf.MappedTable;
import org.jooq.conf.RenderMapping;
import org.jooq.conf.Settings;
import org.jooq.impl.TableImpl;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Pattern;

/**
* @param <R> row
* @param <S> sharding value
*/
public class ConfigurationHolder<R, S> {

private final LoadingCache<S, Configuration> cache;
private final Function<R, S> shardingFn;

/**
* @param shardingFn (shardingParameter) -> shardingValue
* @param renameFn (originalTableName, shardingValue) -> shardedTableName
*/
public static <R, S> ConfigurationHolder<R, S> newInstance(Configuration configuration,
TableImpl table,
Function<R, S> shardingFn,
BiFunction<String, S, String> renameFn) {
return new ConfigurationHolder<>(configuration, table.getName(), shardingFn, renameFn);
}

private ConfigurationHolder(Configuration configuration,
String originalName,
Function<R, S> shardingFn,
BiFunction<String, S, String> renameFn) {
this.shardingFn = shardingFn;
this.cache = CacheBuilder
.newBuilder()
.build(new CacheLoader<S, Configuration>() {
@Override
public Configuration load(S s) {
Settings settings = new Settings()
.withRenderMapping(new RenderMapping()
.withSchemata(new MappedSchema()
.withInputExpression(Pattern.compile(".*"))
.withTables(new MappedTable()
.withInput(originalName)
.withOutput(renameFn.apply(originalName, s)))));
return configuration.derive(settings);
}
});
}

public Configuration get(R shardingParameter) {
return cache.getUnchecked(shardingFn.apply(shardingParameter));
}
}

Use

1
2
3
4
5
6
7
8
DefaultConfiguration config;
TableImpl<Record> fakeTable;

ConfigurationHolder<Integer, Integer> holder = ConfigurationHolder.newInstance(config, fakeTable, id -> id & (1 << 4), (original, val) -> oldName + val);

int id = 1000;
DSL.using(holder.get(id))
.selectFrom(table);

解释

最初试想 jooqSQL 语句来源于对象, TableImpl 对象的构造函数中有一个包含名称的构造函数.

1
2
3
public TableImpl(String name) {
this(DSL.name(name));
}

似乎是这个决定了表名. 那么创建一个修改过表名的 TableImpl 对象应该能实现表名的修改. 结果当然未尝所愿.

这个构造器只是用来 alias 的 (取一个别名).

关于表的重命名, 官网上给出的做法是

1
2
3
4
5
6
7
Settings settings = new Settings()
.withRenderMapping(new RenderMapping()
.withSchemata(new MappedSchema()
.withInput("DEV")
.withTables(new MappedTable()
.withInput("AUTHOR")
.withOutput("MY_APP__AUTHOR"))));

修改 Settings, 指定相应的 Schema 的相应的 Table 进行重命名.

于是, 就有了上述代码. 对 Configuration 进行 derive 且缓存. 使用时, 从 LoadingCache 中获取派生的 Configuration , 使用 DSL.using(Configuration configuration) 进行 SQL 操作.

总结

尽整些没屁用的, 好好的数据库分表不用, 非要折腾个 mybatis 插件分表.

后续

1
2
3
public static DSLContext using(Configuration configuration) {
return new DefaultDSLContext(configuration);
}

DSLContext.using 是创建一个新的 DefaultDSLContext, 其实可以把 DSLContext 给缓存起来, 而不仅仅是 Configuration.

Gitpage

用静态 html 编写渲染 markdown 显然是一个好主意.

Gitpage 本身提供的是 Jekyll, Jekyll 在 windows 下环境准备就很麻烦了, 于是找了找其他的, 就 hexo 了.

Hexo

部署

Travis CI

GitHub Pages 按照官方说明配置 Travis CI, 在 Step 10 的时候遇到了问题.

在 Hexo 官方文档的配置中, Travis CI 将 build 推到了 gh-pages 分支. 而 GitHub Pages 的部署分支无法修改.

根据 github 官方说明

User pages must be built from the master branch

username.github.io 被认为是 user pages, 而 user pages 只能从 master branch 构建.

既然 Gitpages 的构建分支无法修改, 那只能修改 Travis CI 配置, 把 build 结果推到 master 分支.

Travis Docs 中找到目标分支的配置是 deploy.target_branch

修改 .travis.yml

1
2
deploy:
target_branch: master

这样, Travis CI 会将编译结果推到 github/repository 的 master 分支.

这就得需要另一个分支了, 用于存放源文件, 创建一个新分支, 姑且命名为 src 吧, 将源文件推到 src 分支. 同时, 需要修改 .travis.yml.

1
2
3
4
5
6
branches:
only:
- src
deploy
on:
branch: src

这样, Travis CI 只会在收到 src 分支 push 的时候才会编译 src 分支.

同时, 再建一个 dev 分支, 用于开发, 总不能写到一半的东西就放那, 确定写完之后, 再 merge dev 到 src.

hexo-deployer-git

有没有必要用 Travis CI? 其实是没有的.

就在上一篇坑爹文档下面 2 行, 就有个使用 hexo-deployer-git 进行部署的文档.

hexo-deployer 是本地插件, 在本地编译后上传到指定分支. 官网文档里配置也写的很清楚.

主题

挑选主题

部署算是完了, 接下来得选择一个 theme. 不同的 theme 差距还是很大的.

Hexo Themes 里有很多主题, 但使用情况就有些堪忧了.

Hexo 的 theme 的使用方式是将 theme 下载下来, 放到 ./themes/ 目录下. 在 _config.yml 中修改 theme 设置.

绝大部分主题会推荐 git clone *** themes/{theme_name}, git clone 到 themes目录下. 这样 clone 下来的是默认分支, 很多主题维护不佳, 默认分支甚至有些bug…

贴一下我找的几个主题吧.

clexy 这是我找的第一个主题, 相当的简洁.

chan 同样也是一个简洁的主题, 但是不知为何, 修改 _config.yml 无法生效, 放弃了.

期间, 还看见 2 个很漂亮的主题.

diaspora 相当精美的一个主题, 喜欢展示图片的朋友会很喜欢.

fluid material design, 很漂亮, 维护人数还挺多的. 主题好不好用, 主要看维护的好不好. 除非像第一个主题一样, 真的很简洁.

我懒得折腾一堆图片, 最终选择了 next.

NexT

NexT 维护的很好, 功能丰富, 使用起来很方便.

NexT 推荐的安装方式是 git clone https://github.com/theme-next/hexo-theme-next themes/next.
而 NexT 的配置在 ./themes/next/_config.yml 里.
如果修改这个, 更新时 pull 会比较麻烦, 很可能会引起冲突.
里面有个 override 属性, 查看注释.

If false, merge configs from _data/next.yml into default configuration (rewrite).
If true, will fully override default configuration by options from _data/next.yml (override). Only for NexT settings.
And if true, all config from default NexT _config.yml must be copied into next.yml. Use if you know what you are doing.
Useful if you want to comment some options from NexT _config.yml by next.yml without editing default config.
override: false

也就是说, 默认情况下, _data/next.yml 会覆盖掉 ./themes/next/_config.yml 的配置. 这样就很容易了. 建一个 ./source/_data/next.yml 文件, 把配置写进去. 这样就不用修改 ./themes/next 里的内容.

主题与部署

目前 ./themes/next 是没有上传 github 的, 这样整个工程是不完整的, Travis CI 是无法编译的.

要不要把 ./themes/next 上传?

  • 上传也会导致 next 更新的时候变得有些麻烦.
  • 不上传, 就只能本地编译, hexo-deployer 部署

想想别的办法.

Travis CI 的工作流程是, 执行 script 再到 after. Travis CI 是绑定 github 的, Travis CI 环境应该也能执行 git 命令.
.travis.ymlhexo generate 前加上一行

1
2
3
script:
- git clone https://github.com/theme-next/hexo-theme-next themes/next
- hexo generate # generate static files

404

网上找了很多关于 404 配置的内容, 都无法生效. 后面, 找到了一个 github issues 才明白, 本地重定向是无效的. 所以, 无论怎么设置, 本地 hexo server 都无法进行 404 页面重定向. 不过, 还是可以通过 http://localhost:4000/404.html 进行查看修改页面的.

我没特别准备 404 页面, 就写了一个 md page.

1
2
3
4
5
---
title: 404
comments: false
permalink: /404
---

是否需要这个 permalink: /404 我就不清楚了, 毕竟本地无法重定向, 得部署到 github pages 上才能检查.

sitemap

blog 里能加的配置还挺多的, 今天还研究了下 sitemap 与 google search console.

1
npm install hexo-generator-sitemap --save

首先, 添加 hexositemap 插件. 再在 _config.yml 里加上配置.

1
2
3
sitemap:
path: sitemap.xml
rel: true

部署完成之后, 就可以去 Google Search Console 里添加站点.

/source/ 下添加 robots.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
User-agent: *
Allow: /
Allow: /about/
Allow: /archives/
Allow: /categories/
Allow: /tags/

Allow: /images/

Allow: /css/
Allow: /js/
Allow: /lib/

Sitemap: https://icatream.github.io

Robots testing

网上看到的内容都是

1
2
3
Disallow: /css/
Disallow: /js/
Disallow: /lib/

但这样会导致 Googlebot 的抓取异常. 这些内容也都应该被允许抓取.

hexo 官方的 hexo-generator-sitemap 似乎不够 SEO (search engine optimization) 友好. 考虑换其他的 sitemap-generator.

总结

最终没有上传 ./themes/ , Travis CI 通过 git clone 获取 ./themes/next, 之后编译.

那和直接使用 hexo-deployer 有什么差距吗?

不知道…

MSVC

Rust官网 提供了 rustup-init.exe.
除此之外, 还需要一个c编译器. windows环境说的也不是很清楚.
好在9102年了, 微软出了一个简单的安装工具 vs_buildtools.
在这个页面下 Visual Studio Download, 找到 Visual Studio 生成工具 下载运行, 选择需要的功能安装即可, 无需安装整个 Visaul Studio.

Proxy

国内嘛, cargo 当然是需要 proxy 的.
C:\Users\username.cargo 下创建 config 文件.
内容如下:

1
2
3
4
5
[http]
proxy = "127.0.0.1:1080"

[https]
proxy = "127.0.0.1:1080"
  • rustup 也需要 proxy.

  • cmd proxy

1
2
set http_proxy=127.0.0.1:1080
set https_proxy=127.0.0.1:1080
  • powershell proxy
1
2
$ENV:HTTP_PROXY=127.0.0.1:1080
$ENV:HTTPS_PROXY=127.0.0.1:1080

Vscode Debug

vscode 安装 Rust Extension Pack 插件(全套Rust插件), C/C++, Native Debug 插件, 就可以用 msvc 工具链 debug 了. 但每次都得改需要 debug 的 .exe 文件名, 很麻烦(不知道有没有更好的办法). 而且, 在查看 Option<Box<T>> 的时候会出些问题, 明明是 Some 却显示 None.

GNU

Jetbrains 的 Clion 只能用 gnu 工具链进行 debug.

工具链切换

1
2
3
4
rustup default stable-msvc
rustup default stable-gnu
rustup default nightly-msvc
rustup default nightly-gnu

安装 mingw64

windows 下安装 gnu 环境需要安装 mingw64.

mingw-w64.org 里有大量 toolchains, 选择 MingW-W64-builds 安装即可.
MingW-W64-builds 是一个 installer, 也就是实际内容还是得再下载的, 然而国内显然无法下载. 这次 proxy 也失败了(可能得路由器 proxy 了). 不过可以直接找到文件源下载.

mingw-w64/files 里有 2 * 2 * 2 个版本. installer 的功能仅仅是在这些版本中选择.
其中, x86_64i686 分别是 64 位和 32 位, 我们当然是选择 64 位了.
sehsjlj 是异常处理, 其中 seh 是 windows 原生的, 性能更好, 我们反正不用在意其他细节, 选 seh 就完事了.
posixwin32 是多线程相关的, 具体差距我没弄清楚, 大多数还是选 posix. 所以选择最新的 x86_64-posix-seh 下载就好.

再将 rustup 切换到 gnu 工具链, Clion 中设置一下 Toolchains 就可以使用 Clion 进行 debug 了. Clion 的 debug 界面就清晰很多了, 也不用每次在配置文件中修改 .exe 文件名.

但是, Option<Box<T>> 完全没有内容, 之前 vscode 存在异常, Clion 里直接看不了堆内存…

踩坑

最开始装 mingw 的时候, 找来找去, 看推荐装 win-builds, 就装了 win-builds . 第一次走了狗屎运了, 居然把 win-builds 装完了.

切换到 gnu 工具链, 可以编译运行, 但开始 debug 就卡住, 过一会, Clion 异常, commands timed out. 网上也没找到原因, 暂时就把这事放了一段时间.

后面想想是不是之前 win-builds 没有安装完全, 在 mingw-w64.org 里找到 win-builds. 按照下面的 Proxies 说明, 重新安装了一次 (win-builds.exe 的命名不同, 运行界面居然不一样!!). 这次用 wget 把文件全下载下来再装, 完了还是一样, debug 就卡住.

网上查了查明白了, 确实是 win-builds 的问题, win-builds 更全面, 主要是用于交叉编译的, mingw-w64 的兼容性更好.

总结

这一趟下来, 别的没啥, proxy 命令学了很多.