半冷半暖秋天

2010-03-23

MySQL Workbench

Filed under: 文档及资源 — 标签:, , — sunu @ 18:27:20

google.cn消失后我唯一感到不方便的就是没法使用快照功能了,以往虽然不能访问某些搜索结果,但是g.cn的文本快照即是可以查看的。

MySQL Workbench 是一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。你可以用MySQL Workbench设计和创建新的数据库图示,建立数据库文档,以及进行复杂的MySQL 迁移。

中文支持
其实不应该这样说,它本身是支持中文的,只是需要设置一下字体才能显示汉字。”Tools->Options->Fonts”把所有Tahama都换成“新宋体”。
这样在设计表字体的时间就可以输入并显示中文了,否则输入后消失了。

MySQL好像不支持用汉字做数据库表的名称,但是做为字段还是可以的。与其使用不伦不类的中式英文做字段,还不是大方地写上汉字来得爽,看得明白也无需时时为自己蹩脚的英语感到惭愧。

SE和OSS版本
前者是商业版本,后者是开源版本,其它就不用说了。

商业版本下载地址:
1. http://rs408.rapidshare.com/files/182600047/mysql-workbench-se-5.0.22-win32.rar
2. http://drop.io/j3vtnu5

开源版下载地址:
http://dev.mysql.com/downloads/workbench/

2010-03-15

WIN32 API 之InsertMenu

Filed under: C/C++ — 标签: — sunu @ 11:47:01

InsertMenu-函数功能
该函数插入一个新菜单项到菜单里,并使菜单里其他项下移。

InsertMenu-函数原型
BOOL InsertMenu(HMENU hMenu,UINt uPosition,UINT uFlags,UINT uIDNewltem,LPCTSTR lpNewltem);

InsertMenu-主要参数

hMenu:将被修改的菜单的句柄。
uPosition:指定新菜单项将被插入其前面的菜单项,其含义由参数uFlagS决定。
uFlags:指定控制参数uPosition的解释的标志、新菜单项的内容、外观和性能。此参数必须为下列值之一和列于备注里的一个值的组合。
MF_BYCOMMAND:表示uPosition给出菜单项的标识符。如果MF_BYCOMMAND和MF_BYPOSITION都没被指定,则MF_BYCOMMAND为缺省的标志。
MF_BYPOSITION:表示uPosition给出新菜单项基于零的相对位置。如果uPosition为OxFFFFFFFF新菜单项追加于菜单的末尾。
uIDNewltem:指定新菜单项的标识符,或者当参数uFlags设置为MF_POPUP时,指定下拉式菜单或子菜单的句柄。
LpNewltem:指定新菜单项的内容。其含义依赖于参数UFlags是否包含标志MF_BITMAP,MF_OWNERDRAW或MF_STRING。如下所示:
MF_BITMAP:含有位图句柄。MF_STRING:以`\0’结束的字符串的指针(缺省)。
MF_OWNERDRAW:含有被应用程序应用的32位值,可以保留与菜单项有关的附加数据。当菜单被创建或其外观被修改时,此值在消息WM_MEASURE或WM_DRAWITEM的参数IParam指向的结构中、成员itemData里。
返回值:如果函数调用成功,返回值非零;如果函数调用失败,返回值为零。若想获得更多的错误信息,请调用GetLastError函数。
备注:一旦菜单被修改,无论它是否在显示窗口里,应用程序必须调用函数DrawMenuBar。
下列标志可被设置在参数uFlagS里:
MF_BITMAP:将一个位图用作菜单项。参数IpNewltem里含有该位图的句柄。
MF_CHECKED:在菜单项旁边放置一个选取标记。如果应用程序提供一个选取标记位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。
MF_DISABLED:使菜单项无效,使该项不能被选择,但不使菜单项变灰。
MF_ENABLED:使菜单项有效,使该项能被选择,并使其从变灰的状态恢复。
MF_GRAYED:使莱单项无效并变灰,使其不能被选择。
MF_MENUBARBREAK:对菜单条的功能同MF_MENUBREAK标志。对下拉式菜单、子菜单或快捷菜单,新列和旧列被垂直线分开。
MF_MENUBREAK:将菜单项放置于新行(对菜单条),或新列(对下拉式菜单、子菜单或快捷菜单)且无分割列。
MF_OWNERDRAW:指定该菜单项为自绘制菜单项。菜单第一次显示前,拥有菜单的窗口接收一个WM_MEASUREITEM消息来得到菜单项的宽和高。然后,只要菜单项被修改,都将发送WM_DRAWITEM消息给菜单拥有者的窗口程序。
MF_POPUP:指定菜单打开一个下拉式菜单或子菜单。参数uIDNewltem下拉式菜单或子菜单的句柄。此标志用来给菜单条、打开一个下拉式菜单或子菜单的菜单项、子菜单或快捷菜单加一个名字。
MF_SEPARATOR:画一条水平区分线。此标志只被下拉式菜单、子菜单或快捷菜单使用。此区分线不能被变灰、无效或加亮。参数IpNewltem和uIDNewltem无用。
MF_STRING:指定菜单项是一个正文字符串:参数IpNewltem指向该字符串。
MF_UNCHECKED:不放置选取标记在菜单项旁边(缺省)。如果应用程序提供一个选取标记位图(参见SetMenultemBitmaps),则将选取标记位图放置在菜单项旁边。

下列标志组不能被一起使用:

MF_BYCOMMAND和MF_BYPOSITION
MF_DISABLED,MF_ENABLED和MF_GRAYED
MF_BITMAJP,MF_STRING,MF_OWNERDRAW和MF_SEPARATOR
MF_MENUBARBREAK和MF_MENUBREAK
MF_CHECKED和MF_UNCHECKED
Windows CE环境下,不支持参数fuFlags使用下列标志:
MF_BTMAP;MF_DISABLE
参数项如果没变灰,不能使其无效。要使菜单项无效,用MF_GRAYED标志。
Windows CE 1.0不支持层叠式菜单。在使用Windows CE 1.0时,不能将一个MF_POPUP菜单插入到另一个下拉式菜单中。

播放横线
InsertMenu(Menu, menuIndex, MF_SEPARATOR or MF_BYPOSITION, 0, nil);

插入普通菜单
InsertMenu(Menu, 位置, MF_SEPARATOR or MF_BYPOSITION, 菜单编号, PChar(‘Menu’));

如果是播放子菜单
InsertMenu(Menu, 位置, MF_SEPARATOR or MF_BYPOSITION or MF_POPUP, 菜单编号, PChar(‘Menu’));

在子菜单中,“位置”参数决定了子菜单的排序,为这个鸟参数折腾了好久。

2010-03-07

将linux安装于加密分区上

Filed under: linux相关 — 标签:, , — sunu @ 15:10:36

目的:将linux安装在加密的分区中,使得即使硬盘丢失别人也无法获取数据。陈老师肯定很喜欢。。。
实现:

  1. 使用encryptset系列工具创建加密分区
  2. 复制系统所有文件到加密后的分区
  3. 创建initrd,放在未加密的分区中,用grub引导

1. 首先需要准备以下工具
cryptsetup(cryptsetup-luks)
device-mapper
util-linux

2. linux内核必须要加载aes模块

root[~]#modprobe aes
root[~]#cat /proc/crypto | grep aes

name      : aes
driver    : aes-asm
module    : aes_i586
name      : aes
driver    : aes-generic
module    : aes_generic

3. 加密分区

root[~]#cryptsetup –verbose –verify-passphrase -c aes-cbc-plain luksFormat /dev/sda2

输入密码。

4. 挂载+格式化+复制系统文件

root[~]#cryptsetup –verbose –verify-passphrase -c aes-cbc-plain luksFormat /dev/sda2
root[~]#cryptsetup luksOpen /dev/sda2 mydisk
root[~]#ls /dev/mapper/
control mydisk
root[~]#mkfs.ext4 /dev/mapper/mydisk -O uninit_bg -E lazy_itable_init=1
root[~]#mkdir -p /mnt/mydisk;
root[~]#mount /dev/mapper/mydisk /mnt/mydisk
root[~]# … 复制所有系统文件到 /mnt/mydisk中

4. 创建initrd
grub是不支持从crypt_LUKS加密分区启动的,所以需要准备一个单独的未加密小分区存放内核和initrd.

root[~]#mkinitrd //会在/boot/下生成initrd-tree目录,是最简单的initrd目录结构
root[~]#cd /boot/initrd-tree
root[~]# … //修改文件:luksdev为加密分区/dev/sda2, rootfs为ext4, rootdev为/dev/mapper/mydisk
root[~]# … //复制静态版的cryptsetup及device-mapper完整地到 initrd-tree相应的目录下.
root[~]# … //因为在initrd-tree/init启动脚本中会使用到,用来打开加密的分区,而默认的initrd中是没这些工具的
root[~]# … //复制内核的aes模块文件 /lib/modules/版本/kernel/crypto/* 及/lib/modules/版本/kernel/arch/x86/crypto/*到initrd-tree/lib/下。如果内核已经内嵌了aes则不需要了
root[~]#mkinitrd //再次运行mkinitrd会将/boot/initrd-tree打包成/boot/initrd.gz

5. 在grub启动中加上initrd /boot/initrd.gz
如此一来,在启动的过程中,将会提示输入密码.如果密码不对,则系统不会启动。

2010-03-04

spserver+jsoncpp+superobject

Filed under: C/C++ — 标签:, , , , — sunu @ 20:47:05

http://code.google.com/p/spserver/

SPServer is a server framework library written on C++ that implements the Half-Sync/Half-Async and Leader/Follower patterns. It’s based on libevent in order to utilize the best I/O loop on any platform.

http://jsoncpp.sourceforge.net/

jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.

http://code.google.com/p/superobject/

The Json toolkit is a parser/writer for JSON data format. This toolkit is designed to work with Delphi and FreePascal (win32, win64, linux32, linux64, MacOSX Intel)

正在写一个文件服务器,用到上面的三样东西。这周已基本熟悉spserver框架,完成自定义数据包协议设计,在此基础上实现了多文件同时传输、续传及校验部分。单个数据包采用字符串、二进制相结合的形式,对一些细小而繁琐的命令和参数打包成json字符串,而相对比较长的纯数据则保持原样,服务器支持不规则大小的数据包(因为整个包采用[包大小,4字节]+实际数据的形式)。服务器会完整地接收每个数据包,自动解析每个参数,并调用相应的业务处理函数。

2010-03-03

Unix时间戳/Unix Timestamp

Filed under: C/C++ — sunu @ 02:26:26

Unix时间,或称POSIX时间是Unix或类Unix系统使用的时间表示方式:从协调世界时(UTC时间)1970年1月1日0时0分0秒起至现在的总秒数,不包括闰秒。UNIX时间戳的“0”按照ISO 8601规范为 :1970-01-01T00:00:00Z. 一个小时表示为UNIX时间戳格式为:3600秒;一天表示为UNIX时间戳为86400秒,闰秒不计算。在大多数的UNIX系统中UNIX时间戳存储为32位,这样会引发2038年问题或Y2038。
协调世界时2009年2月13日23时31分30秒(即北京时间2009年2月14日07时31分30秒)为Unix时间戳的“1234567890”。

以下时间以UTC时间为准,比如要转换的是北京时间,则先要减少8小时才是UTC时间,北京时间在东八区

转换代码如下: #摘自http://blog.chinaunix.net/u1/38994/showart_303272.html,稍做调整

typedef struct t_xtime {
  int year; int month;  int day;
  int hour; int minute;  int second;
} _xtime ;

#define xMINUTE   (60             ) //1分的秒数
#define xHOUR      (60*xMINUTE) //1小时的秒数
#define xDAY        (24*xHOUR   ) //1天的秒数
#define xYEAR       (365*xDAY   ) //1年的秒数

//---------------------------------------------------------------
//【  版          本  】v1.0
//【  函  数  名  称  】uint32 xDate2Seconds(_xtime *time)
//【 创建人及创建时间 】gliethttp 2006-06-08 10:19
//【 修改人及修改时间 】
//【  修  改  原  因  】
//【  功  能  描  述  】该函数计算从1970年1月1日0时0分0秒起到当前时间所经过的秒数
//---------------------------------------------------------------
unsigned int  xDate2Seconds(_xtime *time)
{
  static unsigned int  month[12]={
    /*01月*/xDAY*(0),
    /*02月*/xDAY*(31),
    /*03月*/xDAY*(31+28),
    /*04月*/xDAY*(31+28+31),
    /*05月*/xDAY*(31+28+31+30),
    /*06月*/xDAY*(31+28+31+30+31),
    /*07月*/xDAY*(31+28+31+30+31+30),
    /*08月*/xDAY*(31+28+31+30+31+30+31),
    /*09月*/xDAY*(31+28+31+30+31+30+31+31),
    /*10月*/xDAY*(31+28+31+30+31+30+31+31+30),
    /*11月*/xDAY*(31+28+31+30+31+30+31+31+30+31),
    /*12月*/xDAY*(31+28+31+30+31+30+31+31+30+31+30)
  };
  unsigned int  seconds = 0;
  unsigned int  year = 0;
  year = time->year-1970;       //不考虑2100年千年虫问题
  seconds = xYEAR*year + xDAY*((year+1)/4);  //前几年过去的秒数
  seconds += month[time->month-1];      //加上今年本月过去的秒数
  if( (time->month > 2) && (((year+2)%4)==0) )//2008年为闰年
    seconds += xDAY;            //闰年加1天秒数
  seconds += xDAY*(time->day-1);         //加上本天过去的秒数
  seconds += xHOUR*time->hour;           //加上本小时过去的秒数
  seconds += xMINUTE*time->minute;       //加上本分钟过去的秒数
  seconds += time->second;               //加上当前秒数
  return seconds;
}

//---------------------------------------------------------------
//【  版          本  】v1.0
//【  函  数  名  称  】void xSeconds2Date(unsigned int  seconds,_xtime *time)
//【 创建人及创建时间 】gliethttp 2006-06-08 10:20
//【 修改人及修改时间 】
//【  修  改  原  因  】
//【  功  能  描  述  】秒数转换为年、月、日、时、分、秒
//---------------------------------------------------------------
void xSeconds2Date(unsigned int  seconds,_xtime *time)
{
  static unsigned int  month[12]={
    /*01月*/31,    /*02月*/28,    /*03月*/31,
    /*04月*/30,    /*05月*/31,    /*06月*/30,
   /*07月*/31,    /*08月*/31,    /*09月*/30,
    /*10月*/31,    /*11月*/30,    /*12月*/31
  };
  unsigned int  days;
  unsigned int  leap_y_count;
  time->second      = seconds % 60;//获得秒
  seconds          /= 60;
  time->minute      =  seconds % 60;//获得分
  seconds          /= 60;
  time->hour        = seconds % 24;//获得时
  days              = seconds / 24;//获得总天数
  leap_y_count = (days + 365) / 1461;//过去了多少个闰年(4年一闰)
  if( ((days + 366) % 1461) == 0){//闰年的最后1天
    time->year = 1970 + (days / 366);//获得年
    time->month = 12;              //调整月
    time->day = 31;
    return;
  }
  days -= leap_y_count;
  time->year = 1970 + (days / 365);    //获得年
  days %= 365;                       //今年的第几天
  days = 01 + days;                  //1日开始
  if( (time->year % 4) == 0 ){
    if(days > 60)
      --days;        //闰年调整
    else{
      if(days == 60){
        time->month = 2;
        time->day = 29;
        return;
      }
    }
  }
  for(time->month = 0;month[time->month] < days;time->month++){
    days -= month[time->month];
  }
  ++time->month;          //调整月
  time->day = days;        //获得日
}

Powered by WordPress