2009. 3. 12. 11:09

이통사별 MDN/MIN 조회 방법

MIN은 어떠한 목적에 따른 고유 번호라고 보고, MDN이 실제 폰번호라고 정의를 한다면
요. 이통사별로 HTTP Header로 조회할 수 있는 폰번호가 MIN과 MDN이 같은지 또는 동
일한지를 정리하면 다음과 같습니다.

1) SKT
UserAgent에서 구하는 값이 대부분 MIN과 MDN이 동일합니다.
허나 한가지 경우에 예외가 있는데요.
번호이동을 하면서 기존의 구형 SKT 단말로 가입을 하는 경우입니다.
이 경우 단말의 S/W 적으로 폰번호가 011 또는 017만 입력이 가능하다고 합니다.(SKT
의 얘기)
즉, 구형단말을 가지고 01033334444 번호로 가입을 하면 MIN 번호는 017xxxxxxx와 같은
번호로 부여를 하고, MDN은 01033334444가 되는 것입니다.

결론적으로 UA에 STI로 시작하는 단말은 MIN과 MDN이 같은 단말도 있으나, 다른 단말
도 있을 수 있다는 의미입니다.

그렇다면, MIN 번호를 가지고 MDN을 조회하는 것은 가능한가???
물론, 가능하지만 SKT의 CP에게만 허용을 하고 있습니다.

2) KTF
HTTP Header에서 구한 MIN은 MDN과 동일합니다. 물론, 브라우저에 따라서
821833334444 또는 01833334444, 8201833334444와 같이 다른 string 형태로 올려주는 경
우가 있으니 이런 것만 예외로 잘 처리를 하시면 MDN을 구하실 수 있습니다.

3) LGT
LGT의 경우는 브라우저에 따라서 다른데요.

A. UP Browser
MIN을 올려주지 않고 subno를 올려줍니다.
즉, subno와 MDN은 다르죠... 이 또한 subno로 MDN을 조회할 수 있으나, CP에게만 권
한을 준다고 하는군요.

B. AU / K / Lion Browser
MIN과 MDN이 동일합니다. 단지, UA에서 폰번호를 구하는 string 위치가 다릅니다. 이
부분만 조건에 따라 잘 구하시면 됩니다.

------------------------------------------------------------------------------
참고1 ) AnyBuilder 의 Provisioning 부분에서는 Include로 폰번호를 구하는 것을 제공합
니다.
참고2 ) 본 사이트의 "모바일 강좌"를 보시면 이통사 브라우저별로 string을 설명해 놓은
것이 있으니 참고하세요.

그럼, 즐거운 하루되세요.


----------------- 정한용님의 질문내용입니다. ----------------

>일반 WAP 페이지에서 carrier값하고 min 값을 얻어오면
>이 값은 MIN 값이 잖아요?
>
>DB에 번호 저장해서 사용할때~
>하고
>선물하기 할때 SKT 인지 구분하기 위해서~
>
>MIN 으로 MDN 을 또는 MDN 으로 MIN을 조회해야 될 것 같습니다.
>
>이와 관련해서 ASP 상에서 사용해 보신 분이나...
>
>예제나 샘플 있으시면...
>
>답변이나 메일로 보내 주시면 감사하겠습니다...
>
>이작업 때문에... 한달 고생했네요 ㅠ.ㅠ
>
>도와주세요...

출처 : http://www.anybil.com/community/developer_view.asp?modeType=read&pk=1460&SearchType=title&SearchTEXT=mdn&page=2
2009. 3. 2. 17:22

MySQL 원격접속 권한 설정

mysql 원격접속 권한 설정

>use mysql
>grant all privileges on *.* to 'oops'@'192.168.1.1'
>identified by 'passwd' with grant option;

ip대신 %를 주면 모든 호스트 접속허용!

oops라는 유저가 모든 권한을 부여받을 수 있다. 단 해당 IP의 Host 에서만,

이와 같은 설정은 select host, user from user;로 확인해 볼 수 있다.
2009. 2. 27. 10:32

Oracle DB를 MySQL DB로 마이그레이션

http://mysql.holywar.net/Downloads/Contrib/9168/177/oracledump.pl 

#!/usr/bin/perl -w
use strict;
use vars qw ( @ARGV $dbh $db_database $db_host $db_port $db_user $db_password
$default_precision $default_scale $default_index_length
$with_table_comments $with_col_comments
$no_data $no_foreign_keys $extended_inserts $complete_inserts $add_drop_table
$add_locks $insert_delayed $lock_tables $table_type $net_buffer_length
$nls_date_format $nls_time_format $nls_timestamp_format $verbose $output_tail);
use DBI;

#############################################
#
# oracledump.pl - Dumps table(s) from an Oracle database to MySQL format
#
# Use ./oracledump.pl without args to see usage info.
# You may also change internal default settings below
#
#
# Written by Johan Andersson <johan@andersson.net>, May 2001
# Needs DBI and DBD::Oracle Perl modules to work.
#############################################
#
# Changes by Guilhem Bichot <guilhem.bichot@mines-paris.org>, April 2002 :
# - Fixed little bugs
# * a one-column primary key was never included in the CREATE TABLE statement
# * an Oracle RAW column was not given any MySQL type
# * statements starting by ';' were produced for empty tables with extended-inserts
# - Oracle RAW columns are converted into VARCHAR BINARY or BLOB, instead of
# VARCHAR or TEXT.
# - Added foreign keys information in final ALTER TABLE ADD FOREIGN KEY statements
# and ALTER TABLE ADD INDEX (commented) as InnoDB may need additional indexes
# for referencing and referenced columns
# - Added option --no-foreign-keys, as retrieving foreign keys information
# from the Oracle views takes a long time
# - Added option --table-type=... to specify the MySQL table type
# in the CREATE TABLE statement
# - Added option --net-buffer-length. If using extended inserts, switches to a new INSERT
# when the length of the INSERT statement reaches net-buffer-length.
# - Made the connection method a bit more versatile : if the user specifies the database name,
# it can either be a valid connection descriptor
# alias specified in the tnsnames.ora file, or (this is what I have added) be of the type
# SID@host or SID@host:port .
# - Suppressed the tnsnames.ora check. In certain situations you had to tell the script
# where the tnsnames.ora was, while the Oracle OCI connection was able to find it without help.
# Moreover, 'grep' does not exist on Windows. Finally, if you specify a wrong
# connection alias descriptor, the Oracle connection dies with "TNS : could not resolve
# service name" which is a sufficient error message. So we do not need to check in the script,
# the Oracle connection does it enough.
# - Lenghtened the help message a bit

### SETTINGS #################################
#
# All settings here are default settings that are used if they're
# not specified as argument.
#

# DATABASE SETUP ####
$db_database = $ENV{'ORACLE_SID'} if defined($ENV{'ORACLE_SID'}); # Default Oracle SID
$db_host = undef;
$db_user = getlogin(); # Default username
$db_password = ''; # Default password

# Oracle session parameters for date/time formats. Do not change if you not
# know exactly what you're doing!
$nls_date_format = 'RRRR-MM-DD';
$nls_time_format = 'HH24:MI:SSXFF';
$nls_timestamp_format = "$nls_date_format $nls_time_format";


# DATA TYPE SETTINGS ####
$default_precision = 18; # Default when precision is missing on NUMBER/FLOAT
$default_scale = 0; # - " " - scale - " " - - " " - - " " -
$default_index_length = 10; # This only affects indexes that contain BLOB fields.
# Sets how big in bytes the index should be for those columns.

# MISC. SETTINGS
$no_data = 0; # Sets whether to retrieve table data or just the table structure
$no_foreign_keys = 0; # Sets whether to retrieve foreign keys or not
$with_col_comments = 1; # Enable comments to be included for each column (if they exist in Oracle)
$with_table_comments = 1; # Same, but for comments for each table.
$extended_inserts = 0; # Use extended INSERT INTO syntax to insert
# multiple rows within one statement (MySQL)
$complete_inserts = 0; # Use of complete inserts adds list of table column
# names used, after the INTO word in INSERT INTO
# statements (MySQL)
# Eg.:
# complete: INSERT INTO foo (col1, col2) VALUES (1,2);
# compact (default): INSERT INTO foo VALUES (1,2);
$add_drop_table = 0; # Specifies if we are going to add DROP TABLE
# statements in the output
$add_locks = 0; # Specifies whether to use locks around insert
# statements or not (MySQL)
$insert_delayed = 0; # Specified wheter to use INSERT DELAYED or not (MySQL)
$lock_tables = 0; # If true, all tables will be locked for read before
# fetching anything from them (Oracle)
$net_buffer_length = 1_047_551 ;

$verbose = 0; # If enabled, program activities are printed out on STDERR
##############################################

# Trap some useful signals to avoid seg fault, DBI handles left open etc.
$SIG{'TERM'} = *interrupt;
$SIG{'QUIT'} = *interrupt;
$SIG{'INT'} = *interrupt;

# Put auto-flush on
$| = 1;

# int main( void )
# Main sub routine
sub main {

# Parse arguments and get tables..
my @arg_tables = parseArgs();

# Create a database handle
$dbh = db_connect($db_database, $db_host, $db_port, $db_user, $db_password);
my $sth;

# Use the ALTER SESSION command to change the date format used
$dbh->do("ALTER SESSION SET NLS_DATE_FORMAT = '$nls_date_format'");
$dbh->do("ALTER SESSION SET NLS_TIME_FORMAT = '$nls_time_format'");
$dbh->do("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = '$nls_timestamp_format'");

# Store tables in an array
my @tables;

# Check if any tables are specified as argument(s)
if($#arg_tables < 0) {
# Fetch all tables from USER_TABLES
$sth = $dbh->prepare("SELECT TABLE_NAME FROM USER_TABLES");
$sth->execute();

my @row;
while(@row = $sth->fetchrow_array()) {
push @tables, $row[0];
}
$sth->finish();
}
else {
while(<;@arg_tables>) {
# Check if table exists
$sth = $dbh->prepare("SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME = ?");
$sth->execute($_);

if($sth->fetchrow_array()) {
push @tables, $_;
}
else {
warn "Table $_ does not existn";
}
$sth->finish();
}
}


# for each table

my $table;
foreach $table ( @tables ) {
print STDERR "* Checking table structure for table $tablen" if $verbose;

my @cols = describe_table($dbh, $table);
my %blobcols = (); # Keeps track on blob columns in indexes
my @colslist = ();
my $output = "";
my @quotecol = ();
my $lastcomment;

$output .= "nDROP TABLE IF EXISTS $table;" if $add_drop_table;
$output .= "nCREATE TABLE $table (";
for ( my $i = 0; $i <= $#cols; $i++ ) {
my(undef, undef, $datatype) = convert_dt($cols[$i]{'TYPE'}, $cols[$i]{'LENGTH'});
$output .= "nt".$cols[$i]{'NAME'}."t".$datatype;
$output .= " DEFAULT '".$cols[$i]{'DEFAULT'}."'" if defined($cols[$i]{'DEFAULT'});
$output .= " NOT NULL" if $cols[$i]{'NULL'} eq 'N';
$output .= "," if $i != $#cols;
$output .= "t# ".$cols[$i]{'COMMENT'} if defined($cols[$i]{'COMMENT'}) && $with_col_comments && $i != $#cols;

# We must save the last comment if such exists, otherwise we may get
# an error later since a separating comma may be printed on the wrong place
$lastcomment = $cols[$i]{'COMMENT'} if defined($cols[$i]{'COMMENT'}) && $with_col_comments && $i == $#cols;

# Save the insert values string

if($cols[$i]{'TYPE'} =~ /^(VAR)?CHAR2?|LONG( RAW)?|RAW|DATE$/) { #bug fix
$quotecol[$i] = 1;
}
else {
$quotecol[$i] = 0;
}

# Keep track on blob columns for indexes
if($datatype eq 'TEXT') {
$blobcols{$cols[$i]{'NAME'}} = 1;
}

# Keep a list of the columns to use when fetching data later
push @colslist, $cols[$i]{'NAME'};
}

# Get keys
print STDERR "* Fetching keys for table $tablen" if $verbose;
my %keys = get_keys($dbh, $table, $no_foreign_keys);

# Get primary key
my @pkcols = @{ $keys{'PRIMARY KEY'} };
my $pkstr = "";

if($#pkcols > -1) {
$output .= ",";

# print last column comment if such exist
if(defined($lastcomment)) {
$output .= "t# $lastcomment";
$lastcomment = undef;
}

$output .= "ntPRIMARY KEY (";

for(my $i=0; $i<=$#pkcols; $i++) {
# Keep track on columns in the PK in a string format (used later with indexes)
$pkstr .= $pkcols[$i]."-";

$output .= $pkcols[$i];
# Add index size if column is a blob column. Required by MySQL
$output .= "(".$default_index_length.")" if defined($blobcols{$pkcols[$i]});
$output .= "," unless $i == $#pkcols;
}
$output .= ")";
}
# Primary key done!

# Get foreign keys
my $type;
my @fkcols;
my $rtable;
my @rfkcols;
my $fkstr;
my $add_fk_statement="";


$type='FOREIGN KEY';
my %foreign_keys = %{ $keys{$type} };

my $number_of_foreign_keys = scalar keys(%foreign_keys);
if ($number_of_foreign_keys>=1) {
$add_fk_statement.= "nALTER TABLE $table" ;
}

my $j=0;

while( my($key) = each %foreign_keys ) {
@fkcols = @{ $foreign_keys{$key}{'COLUMNS'} };
$rtable = $foreign_keys{$key}{'RTABLE'} ;
@rfkcols = @{ $foreign_keys{$key}{'RCOLUMNS'} };

$fkstr = "ntADD ".$type." (";
$output_tail .= "n#ALTER TABLE $table ADD INDEX (";

for(my $i=0; $i<=$#fkcols; $i++) {
$fkstr .= $fkcols[$i];
$fkstr .= "," if $i != $#fkcols;
$output_tail .= $fkcols[$i];
$output_tail .= "," if $i != $#fkcols;
}

$fkstr .= ") REFERENCES ".$rtable." (";
$output_tail .= ");n#ALTER TABLE $rtable ADD INDEX (";
for(my $i=0; $i<=$#rfkcols; $i++) {
$fkstr .= $rfkcols[$i];
$fkstr .= "," if $i != $#rfkcols;
$output_tail .= $rfkcols[$i];
$output_tail .= "," if $i != $#rfkcols;

}

$fkstr .= ")";
$fkstr .= "," if $j != ($number_of_foreign_keys-1) ;
$output_tail .= ");";
$j++;

$add_fk_statement .= $fkstr;
}

if ($number_of_foreign_keys>=1) {
$output_tail .= "n#If the ALTER TABLE $table...ADD FOREIGN KEY... statement below fails with errno 150,n#uncomment some of the lines above and re-run the failed statementn";
$output_tail .= $add_fk_statement;
$output_tail .= ";n" ;
}

# Get indexes (non-unique and unique)
my @idxcols;
my $idxstr;
my $tmp_cols;

print STDERR "* Fetching indexes for table $tablen" if $verbose;

for $type ( 'UNIQUE', 'INDEX' ) {
my %indexes = %{ $keys{$type} };

while( my($key) = each %indexes ) {
@idxcols = @{ $indexes{$key} };

$idxstr = "nt".$type." ".$key." (";
$tmp_cols = "";

for(my $i=0; $i<=$#idxcols; $i++) {
# Keep track on index columns in a string format
$tmp_cols .= $idxcols[$i]."-";

$idxstr .= $idxcols[$i];
$idxstr .= "(".$default_index_length.")" if defined($blobcols{$idxcols[$i]});
$idxstr .= "," if $i != $#idxcols;
}

$idxstr .= ")";

# Check if this index is the PK index
# Since the PK already is specified above we should not
# include that index here.. But if the type not is UNIQUE
# this index is not the PK (just a non-unique duplicate of the
# PK index)
#
# You shouldn't be able to create such a index in Oracle
# (it would return an ORA-01408 error), but since MySQL may
# have duplicate indexes of different uniquenesses we do it
# the MySQL way to be sure..
if($tmp_cols ne $pkstr || $type eq 'INDEX') {
$output .= ",";

# Append last column comment if exists
if(defined($lastcomment)) {
$output .= "t# $lastcomment";
$lastcomment = undef;
}

$output .= $idxstr;
}
}
}

# Append last column comment if exists
if(defined($lastcomment)) {
$output .= "t# $lastcomment";
$lastcomment = undef;
}

$output .= "n)".( (defined($table_type)) ? " TYPE=$table_type" : "" ) .";n";

print STDERR "* Printing CREATE TABLE statement for table $tablen" if $verbose;
print $output;

if(!$no_data) {
# Fetch the data
print STDERR "* Obtaining locks on table $table on Oraclen" if $verbose && $lock_tables;
$dbh->do("LOCK TABLE $table IN SHARE MODE NOWAIT;") if $lock_tables;

print STDERR "* Preparing SELECT statement to fetch data from table $tablen" if $verbose;
$sth = $dbh->prepare("SELECT ".join(", ", @colslist)." FROM $table");
$sth->execute();

# Put together the insert statement. Take care of complete/"compact" options
my $insert_stmt = "INSERT ";
$insert_stmt .= "DELAYED " if $insert_delayed;
$insert_stmt .= "INTO $table ";
$insert_stmt .= "(".join(", ", @colslist).") " if $complete_inserts;
$insert_stmt .= "VALUES ";

my $istmt_nprinted = 1;
my $total_length;
my $tmpstr;

print STDERR "* Printing LOCK TABLES statement for table $tablen" if $verbose && $add_locks;
print "LOCK TABLES $table WRITE;n" if $add_locks;

print STDERR "* Starting to print INSERT INTO statement(s)n" if $verbose;


while(my @row = $sth->fetchrow_array()) {

$tmpstr = "(";

for(my $i=0; $i<=$#colslist; $i++) {
if(defined($row[$i]) && $quotecol[$i]) {
$tmpstr .= $dbh->quote(db_escape($row[$i]));
}
elsif(defined($row[$i]) && !$quotecol[$i]) {
$tmpstr .= $row[$i];
}
else {
$tmpstr .= "NULL";
}
$tmpstr .= "," if $i != $#colslist;
}
$tmpstr .= ")";

if(!$extended_inserts) {
print "$insert_stmt$tmpstr;n";
}
else {
if ($istmt_nprinted) {
print "$insert_stmt$tmpstr";$istmt_nprinted=0;
$total_length=length($insert_stmt)+length($tmpstr);
}
else {
if ( ($total_length+length($tmpstr))>($net_buffer_length-100) ) #100 if for security
#break the current extended INSERT statement and start a new one
{
print ";n$insert_stmt";
$total_length=length($insert_stmt)+length($tmpstr);
}
else {
print ",";$total_length+=length($tmpstr)+1;
}
print $tmpstr;
}
}
}

print ";n" if (($extended_inserts == 1) && ($istmt_nprinted == 0));

print "UNLOCK TABLES;n" if $add_locks;
$sth->finish();
print STDERR "* Done! Printed rows for table $tablen" if $verbose;

}
}

print STDERR "* Printing ALTER TABLE ADD FOREIGN KEY statements for all tablesn" if ($verbose && !$no_foreign_keys);
print $output_tail if !$no_foreign_keys;

$dbh->disconnect();
return 1;
}

# void interrupt ( void )
# This sub-routine is taking care of signals sent to the program
sub interrupt {
my ($sig) = @_;
print STDERR "Got $sig-signal; Issuing database disconnect and program exitn";
print STDERR "Warning: Active statements cannot be closed, exiting program now would cause a seg fault.nWarning: Quiting "safely" _without_ disconnecting from the database (to avoid seg. fault)n" if $dbh->{'ActiveKids'};

$dbh->disconnect() if ! $dbh->{'ActiveKids'};

exit(3);
}

# array describe_table( database_handle dbh, scalar table_name )
# Returns an array of hashes with info about the columns in the given table
sub describe_table {
my($dbh, $table_name) = @_;

# Get columns for the specified table
my $sth = $dbh->prepare("SELECT a.COLUMN_ID,
a.COLUMN_NAME,
a.DATA_TYPE,
a.DATA_LENGTH,
a.DATA_PRECISION,
a.DATA_SCALE,
a.NULLABLE,
a.DATA_DEFAULT,
b.COMMENTS
FROM USER_TAB_COLUMNS a, USER_COL_COMMENTS b
WHERE a.TABLE_NAME = ? AND b.TABLE_NAME = a.TABLE_NAME AND b.COLUMN_NAME = a.COLUMN_NAME");
$sth->execute($table_name);

my @row;
my @columns;
my $length;
while(@row = $sth->fetchrow_array()) {
if($row[2] eq "NUMBER" || $row[2] eq "FLOAT") {
# Set length to default precision/scale values when information
# is missing in the data
$length = (defined($row[4])) ? $row[4] : $default_precision;
$length .= ",";
$length .= (defined($row[5])) ? $row[5] : $default_scale;
}
else {
$length = $row[3];
}

# Trim default data (and remove quotes that oracle stores from CREATE/ALTER command)
$row[7] =~ s/^'([^']+)'s*$/$1/ if defined($row[7]);

# Strip linebreaks in comments
$row[8] =~ s/n// if defined($row[8]);

# Build hash of info about this column
my %column = ( 'NAME' => $row[1],
'TYPE' => $row[2],
'LENGTH' => $length,
'NULL' => $row[6],
'DEFAULT' => $row[7],
'COMMENT' => $row[8] );
# Add the info about this column to the @columns array,
# set the index to the COLUMN_ID to get the "original" order
$columns[--$row[0]] = { %column };
}
$sth->finish();

# Return list of hashes
return @columns;
}

# hash get_keys( database_handle dbh, scalar table_name, scalar no_foreign_keys )
# returns hash of hashes with information of the constraints in the given table
#
# hash = {
# 'PRIMARY KEY' = [ COLNAME1, COLNAME2, ... ],

# 'FOREIGN KEY' = {
# KEYNAME => { 'COLUMNS' => [COLNAME1, COLNAME2, ... ],
# 'RTABLE' => RTABLENAME, "R" means referenced
# 'RCOLUMNS' => [ RCOLNAME1, RCOLNAME2, ... ]
# };
# },

# 'UNIQUE' = {
# KEYNAME => [ COLNAME1, COLNAME2, ... ]
# },
# 'INDEX' = {
# KEYNAME => [ COLNAME1, COLNAME2, ... ]
# }
# }

sub get_keys {
my($dbh, $table_name, $no_foreign_keys) = @_;

my %keys = (
'PRIMARY KEY' => [],
'FOREIGN KEY' => {},
'UNIQUE' => {},
'INDEX' => {}
);
my ( @row, $type, $sth );

# Fetch primary key

$type = 'PRIMARY KEY' ;
$sth = $dbh->prepare("SELECT a.constraint_name, a.column_name, a.position
FROM user_cons_columns a, user_constraints b
WHERE a.table_name=? AND a.constraint_name=b.constraint_name AND
b.constraint_type='P'
ORDER BY a.constraint_name, a.position");
$sth->execute($table_name);

while( @row = $sth->fetchrow_array()) {
$keys{$type}[--$row[2]] = $row[1];
}

$sth->finish();
# Primary key done!

# Retrieve foreign keys information
# Slow due to a 3-view join
if (!$no_foreign_keys)
{
$type = 'FOREIGN KEY' ;
$sth = $dbh->prepare("SELECT a.constraint_name, a.column_name, a.position,
c.table_name,c.column_name
FROM user_cons_columns a, user_constraints b,
user_cons_columns c
WHERE a.table_name=? AND a.constraint_name=b.constraint_name AND
b.constraint_type='R'
AND b.r_constraint_name=c.constraint_name
AND a.position=c.position
ORDER BY a.constraint_name");
$sth->execute($table_name);

while( @row = $sth->fetchrow_array()) {
$keys{$type}{$row[0]}{'COLUMNS'}[$row[2]-1] = $row[1];
$keys{$type}{$row[0]}{'RTABLE'} = $row[3];
$keys{$type}{$row[0]}{'RCOLUMNS'}[$row[2]-1] = $row[4];
}

$sth->finish();
# foreign keys done!
}

# Fetch indexes
$sth = $dbh->prepare("SELECT a.index_name, a.uniqueness, b.column_name, b.column_position
FROM user_indexes a, user_ind_columns b
WHERE a.table_name = ? AND b.table_name = a.table_name AND b.index_name = a.index_name
ORDER BY a.uniqueness, a.index_name");
$sth->execute($table_name);

while( @row = $sth->fetchrow_array() ) {
# Get index type; UNIQUE or INDEX (non-unique of course)
$type = "UNIQUE" if $row[1] eq 'UNIQUE';
$type = "INDEX" if $row[1] eq 'NONUNIQUE';

$keys{$type}{$row[0]}[--$row[3]] = $row[2];
}
$sth->finish();

return %keys;
}

# scalar db_escape ( scalar string )
# Escapes a string to be used within a SQL statement
sub db_escape {
my($str) = @_;

my $newstr = "";
for(my $i=0; $i<length($str); $i++) {
my $c = substr($str, $i, 1);

if(ord($c) == 10) {
$newstr .= chr(92).'n';
}
elsif(ord($c) == 13) {
$newstr .= chr(92).'r';
}
elsif(ord($c) == 9) {
$newstr .= chr(92).'t';
}
elsif(ord($c) == 34 || ord($c) == 92) {
$newstr .= chr(92).chr(ord($c));
}
else {
$newstr .= chr(ord($c));
}
}

return $newstr;
}

# list convert_dt( scalar datatype, scalar datalength )
# Converts datatype to mysql format and returns it
sub convert_dt {
my($datatype, $datalength) = @_;

############################################
# Rules are..:
# Datatype (ORA) Length Returns (MySQL)
# NUMBER Any NUMERIC
# DEC Any NUMERIC
# DECIMAL Any NUMERIC
# NUMERIC Any NUMERIC
# DOUBLE PRECISION Any NUMERIC
# FLOAT Any NUMERIC
# REAL Any NUMERIC
# SMALLINT Any SMALLINT
# VARCHAR <256 VARCHAR
# VARCHAR2 <256 VARCHAR
# CHAR <256 CHAR
# VARCHAR2 >255 TEXT
# VARCHAR >255 TEXT
# CHAR >255 TEXT
# LONG <256 VARCHAR
#LONGRAW does not exist, it is LONG RAW
# LONG RAW <256 VARCHAR BINARY (in Oracle RAW means binary data)
# RAW <256 VARCHAR BINARY
# LONG >255 TEXT
# LONG RAW >255 BLOB
# RAW >255 BLOB
# DATE - DATETIME (Since DATE in oracle can include time information!)
#
# List return consists of:
# 1. Datatype name
# 2. Datalength
# 3. Complete datatype spec. to be used within CREATE TABLE statement
#############################################
if($datalength eq '0') {
$datalength = 32767;
}

return ('NUMERIC', $datalength, 'NUMERIC('.$datalength.')') if $datatype =~ /^DEC(IMAL)?|NUMERIC|NUMBER|DOUBLE PRECISION|FLOAT|REAL$/;
return ('INTEGER', 38, 'INTEGER(38)') if $datatype =~ /^(SMALL)?INT(EGER)?$/;

return ('VARCHAR', $datalength, 'VARCHAR('.$datalength.')') if $datatype =~ /^N?VARCHAR2?|LONG$/ && $datalength <= 255;
return ('TEXT', '', 'TEXT') if $datatype =~ /^N?(VAR)?CHAR2?|LONG$/ && $datalength > 255;

return ('VARCHAR BINARY', $datalength, 'VARCHAR('.$datalength.') BINARY') if $datatype =~ /^LONG RAW|RAW$/ && $datalength <= 255;
return ('BLOB', '', 'BLOB') if $datatype =~ /^LONG RAW|RAW$/ && $datalength > 255;

return ('CHAR', $datalength, 'CHAR('.$datalength.')') if $datatype =~ /^N?CHAR$/ && $datalength <= 255;
return ('DATETIME', '', 'DATETIME') if $datatype eq 'DATE';
}

# db_connect( scalar database, scalar host, scalar port, scalar user, scalar password )
# database_handle connects to the database
sub db_connect {
my($database, $host, $port, $user, $password) = @_;

my $connect_string = defined($host) ? ("host=$host;sid=$database".(defined($port) ? ";port=$db_port" : "")) : $database ;

return DBI->connect( "dbi:Oracle:$connect_string", $user, $password,
{ AutoCommit => 0, RaiseError => 0, PrintError => 1, LongReadLen => 0, LongTruncOk => 1 } );
}

# array parseArgs( void )
# returns array of tables given as argument or invokes the printError() sub-routine
# if some error occurs, which exits the program
sub parseArgs {

if($#ARGV < 0) {
printUsage();
exit;
}

my $tmpcmd = undef;
my @arg_tables;
my $db_database_complete;
my $got_db = 0;
my $show_config_only = 0;
my $use_default_db = 0;

while(<;@ARGV>) {
my $arg = $_;
if(defined($tmpcmd)) {
SWITCH: for ($tmpcmd) {
/^user$/ && do {
$db_user = $arg;
$tmpcmd = undef;
last SWITCH;
};
/^password$/ && do {
$db_password = $arg;
$tmpcmd = undef;
last SWITCH;
};
}
}
else {
SWITCH: {
/^-h|--help$/ && do {
printUsage();
exit 0;
};
/^-u|--user=(.+)$/ && do {
if(defined($1)) {
$db_user = $1;
}
else {
$tmpcmd = 'user';
}
last SWITCH;
};
/^-p|--password=(.+)$/ && do {
if(defined($1)) {
$db_password = $1;
}