12 Sep 2012

将MySQL 的数据导入 PostgreSQL

开始学习使用PostgreSQL, 先尝试将MySQL数据导入到PostgreSQL

安装PostgreSQL

sudo apt-get install postgresql postgresql-client postgresql-contrib  

基本按照http://wiki.ubuntu.org.cn/PostgreSQL进行设置就OK了

安装开发工具

sudo apt-get install libpq-dev pgadmin3

PgAdmin3 这是一个桌面 GUI 工具, 可以很方便的管理 PostgreSQL

用到的RubyGems

在 Gemfile 中增加:

gem "pg" 
gem "mysql2"

然后

bundle install

完整的 Ruby 代码

# coding: utf-8
require 'mysql2'
require 'pg'

mysql_client = Mysql2::Client.new(:host => "localhost", :username =>"root", :password => "pa$$word", :database => "my_test", :encoding => "utf8")

postgres_client = PG::Connection.new(:host => "localhost", :dbname => 'mydb', :user => "postgres", :password => "pa$$word")
postgres_client.set_client_encoding('utf8')

mysql_result = mysql_client.query('select `code`,`name`,`level` from `chinese_regions`')

step = 0
mysql_result.each do |row|

  the_code = row['code']
  the_name = row['name']
  the_level = row['level'].to_i
  insert_sql_test = "insert into chinese_regions (\"code\",\"name\",\"level\") values ('#{the_code}','#{the_name}','#{the_level}');"
  postgres_client.exec(insert_sql_test)

  step += 1
  puts '-' + step.to_s + '-' + the_code + '--' + the_name + '--' + the_level.to_s

end

Run 啊 Run 啊的就 OK 了

15 Aug 2012

使用AjaxUpload和Carrierwave在Rails Mongoid中批量上传图片

file-uploader是一个用 Javascrit 编写的文件上传 Libary,在这里我使用CarrierWaveMongoid 来完成多文件的无刷新上传功能

RubyGems

gem 'mongoid', '3.0.4'
gem 'carrierwave', '0.6.2'
gem 'carrierwave-mongoid', :github => 'jnicklas/carrierwave-mongoid', :branch => 'mongoid-3.0' 
gem 'mini_magick', '3.4'
gem 'rack-raw-upload', '1.1.0'

Model

class Screenshot
  include Mongoid::Document
  include Mongoid::Timestamps::Created
  include Rails.application.routes.url_helpers

  attr_accessible :image 
  field :image 

  mount_uploader :image, ScreenshotUploader 

end

Controller

class ScreenshotsController < ApplicationController

  def index
    @screenshots = Screenshot.all.desc(:created_at)

    respond_to do |format|
      format.html # index.html.erb    
      format.js{ render :layout => false}
    end
  end

  def create
    file = params[:qqfile].is_a?(ActionDispatch::Http::UploadedFile) ? params[:qqfile] : params[:file]
    @screenshot = Screenshot.new
    @screenshot.image = file
    if @screenshot.save
      render json: { success: true, src: @screenshot.to_json }
    else
      render json: @screenshot.errors.to_json
    end
  end

  def destroy
    @screenshot = Screenshot.find(params[:id])
    @screenshot.destroy

    respond_to do |format|
      format.html { redirect_to screenshots_path }
      format.js{ 
        @screenshots = Screenshot.all.desc(:created_at)
        render :layout => false
      }
    end

  end

end

Uploader

# encoding: utf-8
require "digest/md5"
require 'carrierwave/processing/mini_magick'

class ScreenshotUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  storage :file

  # Override the directory where uploaded files will be stored.
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end


  process :convert => 'png'

  # Create different versions of your uploaded files:
  version :thumb do
    process :resize_to_fill => [120, 120]
  end

  # Add a white list of extensions which are allowed to be uploaded.
  def extension_white_list
    %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # see http://huacnlee.com/blog/carrierwave-upload-store-file-name-config/
  def filename
    if super.present?
      # current_path 是 Carrierwave 上传过程临时创建的一个文件,有时间标记,所以它将是唯一的
      @name ||= Digest::MD5.hexdigest(File.dirname(current_path))
      "#{@name}.#{file.extension.downcase}"
    end
  end
end

Javascript

  $(document).ready(function(){

    var uploader = new qq.FileUploader({
      debug: true,
      allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'],
      sizeLimit: 1048576, // max size: 1MB
      minSizeLimit: 0, // min size
      multiple: true,
      element: document.getElementById('file-uploader'),
      action: '<%= screenshots_path %>',
      onComplete: function(id, fileName, responseJSON){
        $.getScript("<%= screenshots_path %>");
      },
      onSubmit: function(id, fileName) {
        uploader.setParams({
          xx: "xx",
          yy: 'yy',
          zz: 'zz',       
          authenticity_token: "<%= form_authenticity_token.to_s %>"
        });
      }
    });

});

你可以在 https://github.com/huobazi/ajax-upload-with-carrierwave-mongoid下载完整的示例代码

06 Mar 2012

从typecho转换到Octopress了

人生在于折腾,所以将博客转换到Octopress了
我的博客经历了如下几次变动:
2003年1月,[自己装了个SnowForum],用来写些技术记录之类的东西
—————–>
2004年4月,搬到博客园,以前的记录停止维护,后来数据丢失
—————–>
2009年6月,搬出博客园,转换到Wordpress当时在旧博客上写了script,告知访问者此处停止更新,询问访问者是否停留在当前页,或转向新页面(可能有更新),因此被封号 @_@|||
—————–>
2009年7月,博客又转换到Typecho平台
—————–>
2012年3月,转到Octopress了,一个静态博客生成引擎,现在看到的全都是html页面,我写了几行ruby代码做了转换,在https://github.com/huobazi/typecho-to-octopress,希望对想转换的朋友有用。

24 Jul 2010

在centos上装rubyee,passenger和memcached ,搭建rails环境

流水笔记一则.

我之前已在服务器配置了nginx,php,mysql等,现在先安装ruby企业版

cd /tmp
wget http://rubyforge.org/frs/download.php/71096/ruby-enterprise-1.8.7-2010.02.tar.gz
tar -xzvf ruby-enterprise-1.8.7-2010.02.tar.gz
cd ruby-enterprise-1.8.7-2010.02
./installer

然后按照提示做

设置一下环境变量 
export PATH=/rubyee/bin:$PATH
接着
ruby -v
gem -v
看到版本号,说明rubyee 安装ok

下来
gem install passenger
passenger-install-nginx-module

按照提示在nginx配置文件里增加:

http {
     ...
     passenger_root /rubyee/lib/ruby/gems/1.8/gems/passenger-2.2.14;
     passenger_ruby /rubyee/bin/ruby;
     ...
}

  server {
     listen 80;
     server_name www.yourhost.com;
     root /somewhere/public;   # <--- be sure to point to 'public'!
     passenger_enabled on;
  }

rails 欧了~

下来开始装 memcached,

memcached 的使用需要libeven的支持

cd /tmp
wget http://www.monkey.org/~provos/libevent-1.4.14a-stable.tar.gz
tar -zxvf libevent-1.4.14a-stable.tar.gz
cd libevent-1.4.14-stable
./configure --prefix=/usr
make && make install

cd /tmp
wget http://memcached.org/latest
tar -zxvf memcached-1.4.5.tar.gz
cd memcached-1.4.5
./configure --prefix=/usr/local
make && make install

 现在可以用
service memcached start  


  service memcached stop  

这两个很骚的命令来管理memcached服务了,欧了~

安装mysql gem
gem install --no-rdoc --no-ri mysql -- --with-mysql-dir=/usr/local/mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

安装 ImageMagick

wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz
tar xvfz ImageMagick.tar.gz
cd ImageMagick*
./configure --disable-static --with-modules --with-gs-font-dir=/usr/share/fonts/type1/gsfonts
make
sudo make install
cd ..
rm -Rf ImageMagick*

wget http://rubyforge.org/frs/download.php/70067/RMagick-2.13.1.tar.bz2
tar -jxf RMagick-2.13.1.tar.bz2
cd RMagick*
./configure --disable-static --with-modules --without-perl --without-magick-plus-plus --with-jpeg=yes --with-png=yes --with-tiff=yes --with-quantum-depth=8  --with-gs-font-dir=/usr/share/fonts/type1/gsfonts
ruby setup.rb
ruby setup.rb install
cd ..
rm -Rf RMagick*

最后 上传 rails 程序
接着 rake gems:install

centos安装rmagick出现以下错误:
libMagickCore.so.2: cannot open shared object file: No such file or directory – /usr/lib/ruby/gems/1.8/gems/rmagick-2.8.0/lib/RMagick2.so
解决办法:

ldconfig /usr/local/lib

错误[memcache-client] Could not load SystemTimer gem, falling back to Ruby's slower/unsafe timeout library: no such file to load -- system_timer
rake aborted!

sudo gem install system_timer

Magick::ImageMagickError (unable to read font `/usr/local/lib/ImageMagick-6.6.3/config//usr/share/fonts/type1/gsfonts/n019003l.pfb' @ error/annotate.c/RenderFreetype/1056: `(null)'):
错误

wget http://sourceforge.net/projects/gs-fonts/files/gs-fonts/8.11%20%28base%2035%2C%20GPL%29/ghostscript-fonts-std-8.11.tar.gz/download
 tar -zxvf ghostscript-fonts-std-8.11.tar.gz
解压后拷贝到需要的目录

30 Mar 2010

在rails中不同的view不同皮肤下的js,css,注入js和css到head区域

利用layout可以很好实现这个需求.

在ApplicationHelper内加入如下代码:

def require_js(path)
    content_for :header_js do
      include_js_tag path
    end
  end

  def require_css(path)
    content_for :header_css do
      include_css_tag path
    end
  end

  def include_js_tag(path)
    if not path.starts_with?("http:")
      path = "/themes/#{@setting[:theme]}/javascripts/" + path
    end
    javascript_include_tag path
  end

   def include_css_tag(path)
    if not path.starts_with?("http:")
      path = "/themes/#{@setting[:theme]}/stylesheets/" + path
    end
    stylesheet_link_tag path
  end

(如果你要直接在view或者layout内引入css则可以<%= include_css_tag "global.css" %>,这样生成的路径是带有皮肤目录的)

接下来,修改你的layout的head,加入如下代码:

<%= yield :header_js %>
<%= yield :header_css %>

然后在需要引入js的View内

<% require_js "jquery/jquery.tools.min.js" %>
<% require_js "jquery/jquery.colorbox.min.js" %>

最后run一下,你会看到会在html的head内生成如下html

<script src="/themes/2010v1/javascripts/jquery/jquery.tools.min.js?1269949149" type="text/javascript"></script>
<script src="/themes/2010v1/javascripts/jquery/jquery.colorbox.min.js?1269949147" type="text/javascript"></script>

 

 

24 Sep 2009

rails中的ActiveRecord真性感!

Rails使用的ActiveRecord真性感啊,see see吧

class User < ActiveRecord::Base  
  has_many :articles  
end  
 
class Article < ActiveRecord::Base
  belongs_to :user  
end

然后执行
>> Article.find(1) 会得到延迟加载user对象的sql语句。如下:

SELECT * FROM articles WHERE (articles.id =1) LIMIT 1

当需要访问user对象时,比如用article.user.name会再生成一个sql语句请求数据库。
如果执行
>> Article.find(1,:include => :user) 会得到一次性加载了user的查询

SELECT
articles.`extended_html` AS t0_r6 articles.`excerpt` AS t0_r7
articles.`keywords` AS t0_r8 articles.`allow_pings` AS t0_r10
articles.`allow_comments` AS t0_r9 users.`id` AS t1_r0
articles.`published` AS t0_r11 users.`login` AS t1_r1
articles.`text_filter` AS t0_r12 articles.`id` AS t0_r0
users.`password` AS t1_r2 articles.`user_id` AS t0_r13
articles.`title` AS t0_r1 users.`name` AS t1_r3
articles.`created_at` AS t0_r14 articles.`author` AS t0_r2
users.`email` AS t1_r4 articles.`updated_at` AS t0_r15
articles.`body` AS t0_r3 articles.`permalink` AS t0_r16
articles.`body_html` AS t0_r4 articles.`guid` AS t0_r17
articles.`extended` AS t0_r5
FROM articles LEFT OUTER JOIN users
ON users.id = articles.user_id
WHERE (articles.id = 1)

是不是很优美,很性感涅?