数据

最近有一个项目,有一个表数据结构如下

name description technique_id references_count
name_1 description 1 5
name_2 description 2 4
name_3 description 3 2
name_1 description 1 5
name_2 description 2 4
name_3 description 3 2
name_1 description 1 5
name_2 description 2 4
name_3 description 3 2

需求

现在需要通过一条sql语句, 通过几个 technique_id 查找, 每个technique_id 查找3条, 并且按照references_count降序

实现

1
2
3
4
SELECT * from (
  SELECT *, RANK() OVER (PARTITION BY technique_id ORDER BY reference_count DESC) AS RP FROM gauges
)
G WHERE G.rp <= 3"

参考

http://thehobt.blogspot.jp/2009/02/rownumber-rank-and-denserank.html

写在前面的话

做了多年的项目, 一直使用capistrano发布项目, 这个确实带来很大的便利。但是有点比较麻烦的地方,就是每次部署新的服务器,都像做苦力一样,去安装服务器的环境,后来了解到Chef和knife-solo, 其就可以达到类似capistrano所作的事情, 不过一个是一键发布项目,一个是一键安装服务器环境,好了,让我们开始吧!

准备工作

我们需要一台测试服务器,这个我们需要Vagrant帮我们实现。

安装vagrant

  1. 先到这里下载Vagrant : https://www.vagrantup.com/downloads.html > 注意: 旧的版本是通过gem install vagrant 安装

  2. 安装box

1
vagrant init hashicorp/precise32

到这里发现更多的box: http://vagrantcloud.com

  1. 启动
1
vagrant up
  1. 配置ssh登录不需要密码
1
vagrant ssh-config --host   服务器IP >> ~/.ssh/config

## 安装chef-solo

  1. 安装chef 和 chef-solo
1
2
3
4
5
6
7
8
9
10
gem install chef
gem install knife-solo
或者
bundle init
编辑Gemfile
添加:
source "https://rubygems.org"
gem "knife-solo"
执行:
bundle install --path=vendor/bundle
  1. 初始化knife-solo项目
1
2
3
4
5
knife solo init chef-repo
cd chef-repo
git init
git commit -a -m "initial commit"
knife solo prepare ServerIP --bootstrap-version 11.12.0 # 如果这里不指定版本号, 会提示找不到文件的错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
需要指定这个版本号 --bootstrap-version 11.12.0 # 如果这里不指定版本号, 会提示找不到文件的错误
wnloading Chef 12.0.0.alpha.2 for ubuntu...
downloading https://www.opscode.com/chef/metadata?v=12.0.0.alpha.2&prerelease=false&nightlies=false&p=ubuntu&pv=12.04&m=i686
  to file /tmp/install.sh.5074/metadata.txt
trying wget...
ERROR 404
Unable to retrieve a valid package!
Please file a bug report at http://tickets.opscode.com
Project: Chef
Component: Packages
Label: Omnibus
Version: 12.0.0.alpha.2
Please detail your operating system type, version and any other relevant details
Metadata URL: https://www.opscode.com/chef/metadata?v=12.0.0.alpha.2&prerelease=false&nightlies=false&p=ubuntu&pv=12.04&m=i686

通过Knife Solo 安装Nginx

  1. 生成模板文件
1
knife cookbook create nginx -o site-cookbooks
  1. 编辑模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
site-cookbooks/nginx/recipes/default.rb
package "nginx" do
    action :install
end
service "nginx" do
    supports :status => true, :restart => true, :reload => true
    action [:enable, :start]
end
template "nginx.conf" do
    path "/etc/nginx/nginx.conf"
    source "nginx.conf.erb"
    owner "root"
    group "root"
    mode 0644
    notifies :reload , "service[nginx]"
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
user vagrant;  # 这里可以用nginx,但是需要新建这个用户
worker_processes    1;
error_log   /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
    worker_connections 1024;
}
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    server {
        listen <%= node['nginx']['port'] %>;
        server_name localhost;
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
    }
}
  1. 在服务器上安装nginx
1
knife solo cook SERVER_IP

参考

  1. http://qiita.com/torufurukawa/items/e20bdb9791c49d00672e
  2. http://gogojimmy.net/2013/06/01/Chef-Solo-Basic-with-Vagrant/
  3. https://docs.vagrantup.com/v2/getting-started/index.html
  4. http://vagrantcloud.com
1
2
obj.should ...
expect(obj).to ...
1
2
obj.should_not ...
expect(obj).not_to ...
1
2
obj.should =~ //
expect(obj).to match(//)
1
2
[1, 2, 3].should =~ [3, 2, 1]
expect([1, 2, 3]).to match_array([3, 2, 1])
1
2
obj.should > 3
expect(obj).to be > 3
1
2
lambda { ... }.should raise_error
expect { ... }.to raise_error

RSpec 2.14.0 or later

1
2
obj.stub(:foo)
allow(obj).to receive(:foo)
1
2
SomeClass.any_instance.should_receive(:foo)
expect_any_instance_of(SomeClass).to receive(:foo)
1
2
SomeClass.any_instance.stub(:foo)
allow_any_instance_of(SomeClass).to receive(:foo)

RSpec 2.99.0.beta1 or later

1
2
it { should eq(something) }
it { is_expected.to eq(something) }

RSpec 3.0.0.beta1 or later

1
2
obj.stub_chain(:foo, :bar).and_return(something)
allow(obj).to receive_message_chain(:foo, :bar).and_return(something)

如果你的rubymine 不能输入中文,请做这样的修改:

1
 vim /Applications/RubyMine.app/bin/idea.vmoptions

加入下面一行: <div class=’bogus-wrapper’>

<figcaption></figcaption><div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 </pre></td><td class=’code’><pre>-J-Djava.awt.im.style=on-the-spot </pre></td></tr></table></div>
</div> 所以长得这样子:

1
2
3
4
5
-Xms128m
-Xmx512m
-XX:MaxPermSize=250m
-XX:+UseCompressedOops
-J-Djava.awt.im.style=on-the-spot

–EOF–

Attribute Isolated Scope

Defined with an @ symbol Binds a local scope property to the value of a DOM attribute The binding is uni-directional from parent to directive The result is always a string because DOM attributes are strings

images

Binding Isolated Scope

Defined with an = symbol Bi-directional binding between parent and directive You can define the binding as optional via =? Optimal for dealing with objects and collections

images

Expression Isolated Scope

Defined using an & symbol Allows you to execute an expression on the parent scope To pass variables from child to parent expressions you must use an object map

images