404 motivation not found | t_ishidaのブログ

7月/08

24

先日のCreateTable文をスクラップする奴を改良

フレームワーク(笑)のSave系アクションの自動ジェネレート機能を付加した。ってか、create_entites.phpはどうすんだよって感じだね。あっちに統合したら開発のイニシャルコストが減らせるんだが、PHPに書き直すの面倒くさいな。真面目な話、これで吐き出たソースをそのまま使ってはいけません。validate周りとか、これじゃ駄目じゃないので、無いよりは有った方が書きやすいよね?のレベルのものです。改修加えることが前提です。HTMLのエスケープは出力時にやるべきだと考えてる人なので、ここではやってません。

#!/usr/bin/perl -w
use Data::Dumper;
sub say{ print "$_[0]\n" }

my @tbls = ();
my $cur  = undef;
my ( $fn, $sep ) = @ARGV;
$fn || die('ファイルの指定無いよ');
$sep = $sep || "\t";
open my $f, $fn;

while( <$f> ){
  ##空行は無視
  /(?:^\s+$|^\))/
    and next;

  ## create table 行
  /create +table +([^\( ]+)/i
    and push @tbls, $cur
      and $cur = { nm => $1, flds => [], pk => [], idx => [] }
        and next;

  ## 主キーの行
  /primary +key\((.+?)\)/i
    and push @{$cur->{pk}}, $1
      and next;

  ## インデックス定義の行
  /INDEX +([^\(]+)\((.+?)\)/
    and push @{$cur->{idx}}, { nm => $1, fld_nm => $2 }
      and next;

  my %fld = ();
  @fld{ 'dum','nm','dat_type'} = split( / +/ ) and
    delete $fld{'dum'};

  if ( /\((\d+)\)/ ) {
    $fld{dat_type} = ~s/\((\d+)\)//;
    $fld{dat_len}  = $1;
  }

  $fld{NULL}     = $_ =~ /NOT NULL/i ? 'NOT NULL' : 'NULL';
  push @{$cur->{flds}}, \%fld;
}
push @tbls,  $cur;
close $f;
shift @tbls;
say( '----------------------区切り文字-----------------------' );

for( @tbls ){
  say( 'テーブル名' . $sep .  $_->{nm} );
  say( 'フィールド名' . $sep . 'データ型' . $sep . "備考");
  foreach my $fld( @{$_->{flds}} ){
    say( join $sep, ( $fld->{nm}, $fld->{dat_type} ) );
  }
  say();
  say( '主キー' );
  foreach my $pk( @{$_->{pk}} ){
    say( $pk );
  }
  say();
  say( 'インデックス' );
  say( 'インデックス名' . $sep . '対象フィールド' );
  foreach my $idx( @{$_->{idx}} ){
    say( $idx->{nm} . $sep . $idx->{fld_nm} );
  }
  say();
  say();
}

for( @tbls ){
  my $str = '';
  my $ret = { valid =>[], save =>[] };
  foreach my $fld( @{$_->{flds}} ){
    ##valid
    $fld->{NULL} =~ /NOT/i and
    push @{$ret->{valid}} , 'if( !$this->REQUEST["' . $fld->{nm} . '"] ) $err[] = \'' . $fld->{nm} . 'は必須です。\';';

    $fld->{dat_type} =~ /(date|time)/i and
    push @{$ret->{valid}} ,'if( !preg_match( "#(\d{4})/(\d{1,2})/(\d{1,2})#", $this->REQUEST["' . $fld->{nm}  . '"], $tmp ) || !checkdate( $tmp[2], $tmp[3], $tmp[1] ) ) $err[] =\'' . $fld->{nm} . 'はYYYY/MM/DDで正しく入力して下さい\';';

    $fld->{dat_len} and
    push @{$ret->{valid}} ,'if( strlen( $this->REQUEST["' . $fld->{nm}  . '"] ) > ' . $fld->{dat_len} . ') $err[] =\''. $fld->{nm} . 'の文字列が長すぎます。' . $fld->{dat_len} . 'バイト以内で入力して下さい。\';';
    ##save
    push @{$ret->{save}} , '$row->' . $fld->{nm} . ' = $this->REQUEST["' . $fld->{nm}. '"];';
  }

  $str  = "require_once 'ActionBase.php';\n";
  $str .= "require_once '$_->{nm}.php';\n";
  $str .= "class Save$_->{nm} extends ActionBase {\n";
  $str .= "  public function validate(){\n";
  $str .= "    \$err = array();\n";
  $str .= join( "\n", map{ '    ' . $_; } @{$ret->{valid}} ) . "\n";
  $str .= '    if( count( $err ) ) $this->Data["msg"] = join( "\n" , $err ); ' . "\n";
  $str .= '    return !count($err);' . "\n";
  $str .= "  } \n\n";
  $str .= "  public function doService(){\n";
  $str .= '    $row = new ' . $_->{nm} . '();' . "\n";
  $str .= '    $row->search( $this->REQUEST["id"] );' . "\n";
  $str .= join( "\n", map{ '    ' . $_; } @{$ret->{save}} ) .  "\n";
  $str .= '    $row->save();' . "\n";
  $str .= "  }\n";
  $str .= "}\n";
  say( $str );
}
Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

RSS Feed

コメントはまだありません。

Leave a comment!

<< プログラマについて雑文

DBDesignerの吐いたcreate table文をスクラップするスクリプト >>

Find it!

Theme Design by devolux.org

Tag Cloud