首頁

2013年6月5日 星期三

**源碼分享---六**~^

**源碼分享---六**~^













1).*文本框輸入限制樣本 *
**Textbox input*restriction sample**
*<textbox id="telNo" xmlns:w="client" >
  <attribute w:name="doKeyPress_">
    function(evt){
         if(this.getValue().length > 0 ){
           if (!this._shallIgnore(evt, "0123456789"))
              this.$doKeyPress_(evt);
         }else{
           if (!this._shallIgnore(evt, "05"))
              this.$doKeyPress_(evt);
         }
    }
  </attribute>
</textbox>


***************************************************************

2).*CkEDITOR*源模式啟動**
**ckeditor statup withsource mode**
*<zk xmlns:w="http://www.zkoss.org/2005/zk/client">
 <ckeditor>
  <attribute w:name="bind_">
   function () {
    // set the startup mode
    CKEDITOR.config.startupMode = 'source';
    //call the original method
    this.$bind_();
   }
  </attribute>
 </ckeditor>
</zk>



***********************************************************************


3).*Access all list item**
*訪問所有列表項**
*<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<zk>
  <div apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('pkg$.test')" onCreate="@command('Cargar')">
 <listbox id="oListBox" model="@load(vm.persons)" height="200px" mold="paging" autopaging="true">
  <listhead>
   <listheader label="First Name" />
   <listheader label="Last Name" />
  </listhead>
          <template name="model" var="item">
  <listitem>
   <listcell label="@load(item.firstName)"/>   
   <listcell label="@load(item.lastName)"/>
  </listitem>  
          </template>
 </listbox>
 <button label="test">
         <attribute name="onClick">
                  StringBuilder sb = new StringBuilder("");
                   oListBox.renderAll();
                  alert("items->"+oListBox.getItemCount());
               for (Object item : oListBox.getItems()) {
         String i = "";
         for (Object cell : ((Listitem) item).getChildren()) {
          //Solo mostramos las celdas que estén visibles
          if(((Listcell)cell).getListheader()!=null){
            if(((Listcell)cell).getListheader().isVisible()){
             i += ((Listcell) cell).getLabel() + ";";
            }
           }
          }
          sb.append(i + "\r\n");
         }
                  lb.setValue(sb.toString());
         </attribute>
 </button>
 <textbox rows="6" width="300px" id="lb" value="message: " />
</div>
</zk>



************************************************************************


**4).*Enable multiple gods on one system** run by non-root users. **~
**在一個系統**啟用多神模式**非root用戶**運行**
*a)))lib/god.rb )
161    # permissions will be used.
162 162    PID_FILE_DIRECTORY_
DEFAULTS =
['/var/run/god', '~/.god/pids']
163 163  
  164 +  # Array of directory paths to be
 used for the socket file. 
  165 +  # This list will be
searched in order
and the first one that has write 
  166 +  # permission will be used.
  167 +  SOCKET_FILE_
DIRECTORY_DEFAULTS
= ['/var/run/god', '~/.god/sockets']
  168 +  
164 169    # The default Integer port
 number for the
DRb communcations channel.
165 170    DRB_PORT_DEFAULT
 = 17165
166 171  
... ... @@ -188,6 +193,7 @@
class << self
188 193                         :allow,
189 194                         :log_buffer_size,
190 195                         :pid_file_directory,
  196 +                       :socket_file_
directory,
191 197                         :log_file,
192 198                         :log_level,
193 199                         :use_events,
... ... @@ -216,6 +222,7 @@
class << self
216 222    self.allow = nil
217 223    self.log_buffer_size = nil
218 224    self.pid_file_directory = nil
  225 +  self.socket_file_directory = nil
219 226    self.log_level = nil
220 227    self.terminate_timeout = nil
221 228    self.socket_user = nil
... ... @@ -629,51 +636,64 @@
 def self.load(glob)
629 636        Kernel.load f
630 637      end
631 638    end
  639 +  
  640 +  # Setup pid and socket
 file directories,
 and log system.
  641 +  #
  642 +  # Returns nothing
  643 +  def self.setup
  644 +    self.setup_special_file_
directory(PID_
FILE_DIRECTORY_
DEFAULTS, :pid_file_directory)
  645 +    self.setup_special_file_
directory(SOCKET_
FILE_DIRECTORY_
DEFAULTS, :socket_file_directory)
  646 +    
  647 +    if God::Logger.syslog
  648 +      LOG.info("Syslog enabled.")
 if self.log_level
  649 +    else
  650 +      LOG.info("Syslog disabled.")
 if self.log_level
  651 +    end
  652 +  end
632 653  
633   -  # Setup pid file directory
and log system.
  654 +  # Setup special file directory
(pid and socket
at this point)
  655 +  # Requires an array of
directories to try, and
a symbol for the 
  656 +  # corresponding attribute
on this class object.
634 657    #
635 658    # Returns nothing.
636   -  def self.setup
637   -    if self.pid_file_directory
638   -      # Pid file dir was
specified, ensure it is
created and writable.
639   -      unless File.exist?
(self.pid_file_directory)
  659 +  def self.setup_
special_file_directory
(default_directories,
special_file_directory_attribute)
  660 +    special_file_directory =
self.send(special_file_
directory_attribute)
  661 +    nice_directory_text =
 special_file_directory_
attribute.to_s.gsub("_"," ")
  662 +    
  663 +    if special_file_directory
  664 +      # Special file dir was
 specified, ensure it is
 created and writable.
  665 +      unless File.exist?
(special_file_directory)
640 666          begin
641   -          FileUtils.mkdir_p
(self.pid_file_directory)
  667 +          FileUtils.mkdir_p
(special_file_directory)
642 668          rescue Errno::EACCES => e
643   -          abort "Failed to create

pid file directory:
 #{e.message}"
  669 +          abort "Failed to create #
{nice_directory_text}:
 #{e.message}"
644 670          end
645 671        end
646 672  
647   -      unless File.writable?
(self.pid_file_directory)
648   -        abort "The pid file directory
 (#{self.pid_file_directory}) is
not writable by #{Etc.getlogin}"
  673 +      unless File.writable?(special
_file_directory)
  674 +        abort "The pid file directory
 (#{special_file_directory}) is
not writable by #{Etc.getlogin}"
649 675        end
650 676      else
651   -      # No pid file dir specified, try defaults.
652   -      PID_FILE_DIRECTORY_
DEFAULTS.each do |idir|
  677 +      # No special file dir specified,
 try defaults.
  678 +      default_directories.each do |idir|
653 679          dir = File.expand_path(idir)
654 680          begin
655 681            FileUtils.mkdir_p(dir)
656 682            if File.writable?(dir)
657   -            self.pid_file_directory = dir
  683 +            self.send("#{special_
file_directory_
attribute}=".to_sym,dir)
658 684              break
659 685            end
660 686          rescue Errno::EACCES => e
661 687          end
662 688        end
663 689  
664   -      unless self.pid_file_directory
665   -        dirs = PID_FILE_DIRECTORY_
DEFAULTS.map { |x| File.
expand_path(x) }
666   -        abort "No pid file directory exists,
could be created, or is writable
 at any of #{dirs.join(', ')}"
  690 +      unless self.send(special_file_
directory_attribute)
  691 +        dirs = default_directories.map

 { |x| File.expand_path(x) }
  692 +        abort "No #{nice_directory_text}
exists, could be
created, or is writable at any
 of #{dirs.join(', ')}"
667 693        end
668 694      end
669   -
670   -    if God::Logger.syslog
671   -      LOG.info("Syslog enabled.")
672   -    else
673   -      LOG.info("Syslog disabled.")
674   -    end
675   -
676   -    applog(nil, :info, "Using pid
 file directory: #{self.pid_file_directory}")
  695 +    
  696 +    applog(nil, :info, "Using #{nice_
directory_text}: #{self.send(special_file_directory_attribute)}")
if self.log_level
677 697    end
678 698  
679 699    # Initialize and startup the
 machinery that makes god work.


*********************&&& next b

**b*lib/god.rb *
*
... ... @@ -11,10 +11,10 @@ def initialize(command, options, args)
11 11        end
12 12  
13 13        def setup
  14 +        God.setup #necessary to set the proper socket file.
14 15          # connect to drb unix socket
15 16          DRb.start_service("druby://127.0.0.1:0")
16 17          @server = DRbObject.new(nil, God::
Socket.socket(@options[:port]))
17   -
18 18          # ping server to ensure that it is responsive
19 19          begin
20 20            @server.ping

**lib/god.rb *
... ... @@ -11,7 +11,7 @@ class Socket
11 11      #
12 12      # Returns String (file location)
13 13      def self.socket_file(port)
14   -      "/tmp/god.#{port}.sock"
  14 +      "#{God.socket_file_directory}/god.#{port}.sock"
15 15      end
16 16  
17 17      # The address of the socket for a given port


*****************************************************************************************

**多語言系統數據庫**


**多語言系統數據庫**

*比如我们做一个给中国大陆&&
纽伦新港使用的系统,可以确定的
语言就是简体中文、繁体中文和英语,
而且可以确定以后也不会增加语言。
*确定以后是否需要增加语言**
这一点很重要,决定了在数据库
设计时,是否需要考虑多语上的扩展性**
先说在数据库设计时,可以有以下方案实现多语:
一、为每个多语字段建立对应语言的字段列~
比如我们有一个客户表,记录了客户Id、
客户名称、客户地址、客户电话等,其中
客户名称和客户地址是多语的,而且需要支持
简体中文、繁体中文和英语,于是我们可以
将客户表设计如下:
create table Client
(
    ClientId int primary key,
    NameChs nvarchar(50),
    NameCht nvarchar(50),
    NameEng varchar(200),
    AddressChs nvarchar(50),
    AddressCht nvarchar(50),
    AddressEng varchar(200),
    TelephoneNumber varchar(50)
)
**这样做的优点是容易理解,容易查询,一个
客户实例对应的就是数据库中的一条数据,
与普通的非多语数据库无异,而且由于没有
形成新的表,所以也不需要额外的Join,
所以查询效率很高:
insert into Client values(1,'工商银行','工商銀行','ICBC',
'中国北京','中國北京','China,Beijing','13811255555');

select * 
from Client c 
where c.ClientId=1 
二、建立统一的翻译表,在翻译表中使用
多列存储多语言,然后在实体表中外键
引用翻译表。
create table Translation 
(
    TranslationId int primary key,
    TextChs nvarchar(200),
    TextCht nvarchar(200),
    TextEng varchar(200),
)

create table Client
(
    ClientId int primary key,
    NameTranId int references Translation(TranslationId),
    AddressTranId int references Translation(TranslationId),
    TelephoneNumber varchar(200)
)
这样要查询数据时,需要将Translation
表JOIN2次,获得对应的Name和
Address的多语。
insert into Translation values 
(10,'工商银行','工商銀行','ICBC');
insert into Translation values 
(20,'中国北京','中國北京','China,Beijing');
insert into Client values 
(1,10,20,'13811255555');

select c.ClientId,c.TelephoneNumber,
tn.TextChs as NameChs,tn.TextCht as NameCht,tn. 
TextEng as NameEng,
ta.TextChs as AddressChs,ta.TextCht as AddressCht,ta. 
TextEng as AddressEng 
from Client c 
inner join Translation tn 
on c.NameTranId=tn.TranslationId 
inner join Translation ta 
on c.AddressTranId=ta.TranslationIdwhere 
where c.ClientId=1 

**以上的方法都是将多语作为列输出,也就是
说有多少种语言就会有多少对于的列,不利于 
语言的增加下面再介绍将语言以数据行的
形式保存的设计方法,这种方法可以在后期
任意增加语言而不改动数据库Schema.
三、将每个表中需要多语的字段独立出来,
形成一个对应的多语表。
多语表外键关联原表,每个需要多语的字段
在多语表中对应一列,多语表中增加“语言”
字段。同样以Client表为例,那么对应的表 
结构是:
create table Client
(
    ClientId int primary key,
    TelephoneNumber varchar(200)
)
create table Client_MultiLanguages
(
    CLId int primary key,
    ClientId int references Client(ClientId),
    Name nvarchar(200),
    Address nvarchar(200),
    Language char(3)
)
这样的优点是便于扩展,在Schema中并没有
定义具体的语言,所以如果要增加语言的话,
只需要在多语表中增加一行对应的数据即可。
查询也相对比较简单,执行要将原表与对应的 
多语表JOIN,然后跟上具体的语言作为 
WHERE条件,即可完成对数据的查询,
比如要查询Id为1的Client对象的英语实例:
insert into Client values(1,'13811255555');
insert into Client_MultiLanguages values  
(1,1,'工商银行','中国北京','CHS');
insert into Client_MultiLanguages values  
(2,1,'工商銀行','中國北京','CHT');
insert into Client_MultiLanguages values  
(3,1,'ICBC','China,Beijing','ENG');

select c.*,cm.Name,cm.Address 
from Client c inner join Client_MultiLanguages cm  
on c.ClientId=cm.ClientId  
where c.ClientId=1 and cm.Language='ENG'  

四、建立统一翻译表和对应的多语表,
在每个多语列指向翻译表。
create table Translation 
(
    TranslationId int primary key
)

create table Client
(
    ClientId int primary key,
    NameTranId int references Translation(TranslationId),
    AddressTranId int references Translation(TranslationId),
    TelephoneNumber varchar(200)
)


create table TranslationEntity 
(
    TranslationEntityId int primary key,
    TranslationId int references Translation(TranslationId),
    Language char(3),
    TranslatedText nvarchar(200)
)
如果要查询Id为1的Client对应的英语实例,那么脚本为:
insert into Translation values(10);
insert into Translation values(20);
insert into Client values(1,10,20,'13811255555');
insert into TranslationEntity values 
(1,10,'CHS','工商银行');
insert into TranslationEntity values 
(2,10,'CHT','工商銀行');
insert into TranslationEntity values 
(3,10,'ENG','ICBC');
insert into TranslationEntity values 
(4,20,'CHS','中国北京');
insert into TranslationEntity values 
(5,20,'CHT','中國北京');
insert into TranslationEntity values  
(6,20,'ENG','China,Beijing');


select c.ClientId,tne.TranslatedText as Name,
tae.TranslatedText as Address,c.TelephoneNumber
from Client c
inner join TranslationEntity tne
on c.NameTranId=tne.TranslationId
inner join TranslationEntity tae
on c.AddressTranId=tae.TranslationId
where c.ClientId=1 and tne.Language='ENG' and 
 tae.Language='ENG'

**这个数据的插入和查询也太复杂 !
同时也可以注意到在查询时根本没有用到 
Translation表,其实这个表只是标识每个 
数据实例中的多语字段,可以直接使用数据 
库的Sequence生成或者使用GUID,只要 
保证全局唯一即可。另外也可以注意到在
查询时JOIN了2次TranslationEntity 表,
如果一个表的多语字段比较多,比如有10个 
字段有多语,那么查询是就需要JOIN10次,
这个效率会很低。另外还可以注意到,
在WHERE条件中写了2次Language='ENG',
如果多个多语字段,那么就要写多次。刚才 
这个查询写的不够严谨,因为不能保证Name
字段和Address字段必然就有英文值,如果没
有英文值会导致查询结果为空,所以正确的
写法应该是:
select c.ClientId,tne.TranslatedText as Name,tae.
TranslatedText as Address,c.TelephoneNumber
from Client c
left join TranslationEntity tne
on c.NameTranId=tne.TranslationId  and tne.
Language='ENG'left join TranslationEntity tae
on c.AddressTranId=tae.TranslationId and tae.
Language='ENG'where c.ClientId=1 
实际项目中,如果我们使用了NHibernate等
ORMapping工具,那么多语字段就会映射成一
个集合,所以对于某种语言的实例,那么需要
执行N+1次SQL查询,而不是JOIN查询,N是该
对象中多语的属性个数  ***~



********************************************************