用DDLGEN从ASE数据库中提取对象的定义语法

在论坛中看到有人寻找从sybase数据 库中提取表结构的方法。用 dbartisan8.6.1这个第三方工具可以很轻松的实现,我自己也用pb编写过函数能够提取表结构和索引创建语法。
像sybase自带的sybase central也能从中导出ddl。我感觉从sybase central中导出语法时可能利用的就是ddlgen这个工具,原因我认为sybase central和ddlgen都基于java 编写。
先将整理的ddlgen说明以及使用方法贴在下面。

ddlgen

Description

A Java-based tool that generates definitions for server- and database-level objects in Adaptive Server. ddlgen supports Adaptive Server version 11.9.2 and later.

The command-line version of ddlgen is located in $SYBASE/ASEP/bin ( %SYBASE%\ASEP\bin in Windows ).

Syntax

ddlgen

-Ulogin

-Ppassword

-S[server | host_name : port_number ]

[-I interfaces_file ]

[-Tobject_type ]

[-Nobject_name ]

[-Ddbname ]

[-Xextended_object_type ]

[-Ooutput_file ]

[-Eerror_file ]

[-Lprogress_log_file ]

[-Jclient_charset ]

-F[ % | SGM | GRP | USR | R | D | UDD | U | V |
P | XP | I | RI | KC | TR | PC ]

Parameters

-U login

specifies a login name, and is case-sensitive.

-P password

specifies your password.

-S [server | host _ name : port _ number ]

specifies the name of the Adaptive Server. ddlgen looks this name up in the interfaces file or LDAP configuration file. If you specify:

·
-S [host _ name :port _ number ] –
ddlgen uses the host _ name and port _ number provided, and neither interfaces nor LDAP configuration files are read or parsed.

·
-S[server ] -I ddlgen parses the interfaces file specified at the user location for the server name (see the -I parameter description for more information).

·
-S[server ] – without specifying an interfaces file, ddlgen does the following:

a.
ddlgen first tries to read the LDAP configuration file from the standard location

b.
If the LDAP file does not exist, or exists but does not contain an Adaptive Server entry, then the interfaces file is parsed at its standard location for the server name

c.
If the LDAP file exists, then ddlgen uses it to search the server name. The interfaces file is not parsed, and the LDAP configuration file is parsed.

You must use the -S option because ddlgen does not connect to a default server.

-I

specifies the interfaces file name, and corresponds to $SYBASE/interfaces for UNIX , and %SYBASE%\ini\sql.ini for Windows. Use this optional parameter with -S .

-Tobject _ type

specifies the type of object you are creating. If you do not use -T , ddlgen generates DDL for the default database of login. The object types for -T are:

 

Object type  Description 
C  cache
D  default
DB  database
DBD  database device
DPD  dump device
EC  execution class
EG  engine group
EK  encrypted keys
GRP  group
I  index
KC  key constraints
L  login
LK  logical key
P  stored procedure
R  rule
RI  referential integrity
RO  role
RS  remote server
SGM  segment
TR  trigger
U  table
UDD  user-defined datatype
USR  user
V  view
WS  user-defined Web service
WSC  Web service consumer
XP  extended stored procedure

 

-Nobject _ name

specifies the fully qualified name of the object you are creating, such as -Ndb _ name .owner _ name .table _ name .object _ name . The -N option:

·
is required if you specify any object _ type other than DB (database) in the -T parameter.

·
accepts wildcards with the use of % .

·
generates DDL for all items of a specific object type on your server.

·
enforces strict order in which it parses the names in the -Ndb _ name .owner _ name .table _ name .object _ name format. If you only provide three arguments, ddlgen assumes they are owner _ name , table _ name , and object _ name , in that order. Alternatively, you can also use -Nowner _ name .table _ name -Ddb _ name . ddlgen does not impose this restriction if object _ name is an index (I ).

-Ddbname

specifies the name of the database for the object you specify in the -N option. The default is the user’s default database.

-Xextended _ object _ type

differentiates the following:


user tables (OU ) from proxy tables (OD ) when you specify a table as your object type (-TU )
temporary databases (OD ) from nontemporary databases (OU ) when you specify database as your object type (-TDB )
SQLJ procedures (OD ) from stored procedures (OU ) when you specify procedure as your object type (-TP ).

If object _ type (-T ) is U (table) and -X is not specified, ddlgen generates DDL for both user tables and proxy tables. To generate DDL only for:


user tables – use the OU extended object type with the -X option.
proxy tables – use the OD extended object type with the -X option.

ddlgen does not support schema generation for system tables.

 

-Ooutput _ file

specifies an output file for the generated DDL. If you do not specify -O , the DDL you create appears in a console window.

-Eerror _ file

specifies a log file for recording errors. If you do not specify -E , the generated errors appear in a console window.

-Lprogress _ log _ file

specifies a log file for recording the progress of ddlgen . If you do not specify -L , the progress is not recorded.

-Jclient _charset

specifies the character set to use on the client. -Jclient _charset requests that Adaptive Server convert to and from client _charset , the character set used on the client. A filter converts input between client _charset and the Adaptive Server character set.

Omitting -J sets the character set to a default for the platform. The default may not necessarily be the character set that the client is using.

HP platforms – You must use -Jiso_1 to specify the correct character set.

-F

filters out indexes, triggers, and constraints out of table and database definitions in the DDL of table- and database-level objects. The valid filters are:


For tables [ % | I | RI | KC | TR | PC ]


For databases [ % | SGM | GRP | USR | R | D | UDD | U | V | P | XP | I | RI | KC | TR]

The filter options are:

 

 

Filter option  Filters out: 
%  Everything, and retrieves the schema-only definition of a database or table.
SGM  Segments
GRP  Groups
USR  Users
R  Rules
D  Defaults
UDD  Uer-defined datatypes
U  User tables
V  Views
P  Stored procedures
PC  Partition condition
XP  Extended stored procedures
I  Indexes
RI  Referential integrity constraints
KC  Primary- and unique-key constraints
TR  Triggers

 

-v

displays the version and copyright message of ddlgen and returns to the operating system.

 

Examples

Example 1

Caches – Generates DDL for a cache called default data cache on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TC -N"default data cache"

To generate DDL for all caches:

ddlgen -Ulogin -Ppassword -Sserver :port -TC -N%

Example 2

Defaults – Generates DDL for a default called “phondflt” owned by jones in the pubs2 database on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TD -Njones.phonedflt -Dpubs2

Alternatively, because ddlgen allows you to use a fully qualified name in the -N flag, you can omit the -Ddbname and include the database name in the -N option:

ddlgen -Ulogin -Ppassword -Sserver :port -TD -Ndbname .owner .defaultname

To generate DDL for all defaults in a database owned by “owner”:

ddlgen -Ulogin -Ppassword -Sserver :port -TD -Nowner .% -Ddbname

Example 3

Databases – Generates DDL for a database called pubs2 on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TDB -Npubs2

If you do not specify a dbname , ddlgen generates DDL for the default database of login :

ddlgen -Ulogin -Ppassword -Sserver :port

If you do not use the -T parameter, ddlgen generates DDL for a default-type database:

ddlgen -Ulogin -Ppassword -Sserver :port -Ndbname

To generate DDL for all databases:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -N%

Example 4

Database device – Generates DDL for a database device called master running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TDBD -Nmaster

To generate DDL for all database devices:

ddlgen -Ulogin -Ppassword -Sserver :port -TDBD -N%

Example 5

Temporary databases – Generates DDL for all databases, including tempdb :

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -N%

To generate DDL for all temporary databases, use the OD extended database type:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -XOD -N%

Although you can use the OD extended type in Adaptive Server versions 12.5.0.3 and later, versions earlier than 12.5.0.3 issue warning messages. You can safely ignore this message; ddlgen continues processing the command.

To generate DDL for all databases except temporary databases, use the OU extended type:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -XOU -N%

The following generates DDL for a temporary database named tempdb1 :

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -Ntempdb1

The output includes the following:

·
A create temporary database statement


create temporary database tempdb1 on master = 4,asdas = 2
go


An sp_tempdb bind statement where the isql application is bound to tempdb1 :


sp_tempdb 'bind','ap', 'isql', 'DB', 'tempdb1'
go

 

DDL for objects such as views, stored procedures, and tables is not generated along with DDL for a temporary database because these objects are temporary, and are re-created when the server restarts.

When you use the -F parameter to filter a table while generating DDL for a database object, then indexes, referential integrity, key constraints and triggers automatically get filtered, as they are a subset of the table object.

Example 6

Dump device – generates DDL for a dump device called tapedump1 running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TDPD -Ntapedump1

To generate DDL for all dump devices:

ddlgen -Ulogin -Ppassword -Sserver :port -TDPD -N%

Example 7

Execution class – generates DDL for an execution class called EC2 running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TEC -NEC2

To generate DDL for all execution classes:

ddlgen -Ulogin -Ppassword -Sserver :port -TEC -N%

Example 8

Engine groups – generates DDL for an engine group called LASTONLINE running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TEG -NLASTONLINE

To generate DDL for all engine groups:

ddlgen -Ulogin -Ppassword -Sserver :port -TEG -N%

Example 9

Extended stored procedures – generates DDL for the xp_cmdshell extended stored procedure in the pubs2 database, owned by Jones and running on a machine named HARBOR using port 1955, by using the fully qualified dbname .owner .extendedstoredprocedure format with the -N option:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TXP -Npubs2.jones.xp_cmdshell

Alternatively, you can use the -D option instead of using the fully qualified name:

ddlgen -Ulogin -Ppassword -Sserver :port -TXP

    -Nowner .extendedstoredprocedure -Ddbname

To generate DDL for all extended stored procedures:

ddlgen -Ulogin -Ppassword -Sserver :port -TXP -Ndbname .owner .%

Example 10

Filters – Generates DDL for the authors table in the pubs2 database, filtering for all indexes (I ), and referential integrity constraints (RI ), primary and unique key constraints (KC ), triggers (TR ), and partition condition (PC ) from the DDL of a table:

ddlgen -Uroy -Proy123 -TU -Nauthors -Dpubs2 -F%

Alternatively, you can specify each of the filters individually:

ddlgen -Ulogin -Ppassword -TU -Ndbname .owner .table

    -FI,RI,KC,TR

The following generates the definition of table _ name while filtering out foreign keys and primary-unique keys:

ddlgen -Ulogin -Ppassword -TU -Ntable_name -Ddbname

    -FRI,KC

Both of these generate foreign keys for a specified user in the entire database:

ddlgen -Ulogin -Ppassword -TRI -N%.%.% -Ddbname

Or:

ddlgen -Ulogin -Ppassword -TRI -Ndbname %.%.%

Both of these generate DDL for the primary and unique keys of all the tables in a database that begin with “PK”:

ddlgen -Ulogin -Ppassword -TKC -Ndbname .%.%.PK%

Or:

ddlgen -Ulogin -Ppassword -TKC -N%.%.PK% -Ddbname

The following generates schema-only definition of a database:

ddlgen -Ulogin -Ppassword -Sserver :port -TF -Ndbname -F%

Alternatively, you can specify each of the filters individually:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -Ndbname

    -FSGM,GRP,USR,R,D,UDD,V,P,XP,I,RI,KC,TR

The following generates the database DDL skipping the compiled object:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -Ndbname -FTR,D,XP,V,R

The following generates database definition without a table definition:

ddlgen -Ulogin -Ppassword -Sserver :port -TDB -Ndbname

    -FU

Example 11

Groups – Generates DDL for a group called “public” in the pubs2 database, running on a machine named HARBOR using port 1955, by using the fully qualified dbname .groupname format in the -N option:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TGRP -Npubs2.public

Alternatively, you can use the -D option to specify the dbname :

ddlgen -Ulogin -Ppassword -Sserver :port -TGRP -Ngroupname -Ddbname

To generate DDL for all groups:

ddlgen -Ulogin -Ppassword -Sserver :port -TGRP -Ndbname .%

Example 12

Indexes – Generates DDL for an index called au_lname for the table authors owned by dbo, in the pubs2 database:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TI -Ndbo.authors.au_lname -Dpubs2

Alternatively, because ddlgen allows you to use a fully qualified name in the -N flag, you can omit the -Ddbname and include the database name in the -N option:

ddlgen -Ulogin -Ppassword -Sserver :port

    -TI -Ndbname .owner .tablename .indexname

If you use a fully qualified name, you may omit the -D option.

To generate DDL for all indexes for a single table:

ddlgen -Ulogin -Ppassword -Sserver :port -TI

    -Ndbname .owner .tablename .%

To generate DDL for all indexes of all tables in a database:

ddlgen -Ulogin -Ppassword -Sserver :port -TI

    -Ndbname .%.%.%

For example, this generates DDL for all indexes for all tables in the pubs2 database:

ddlgen -Usa -P -SHARBOR:1955 -TI -Npubs2.%.%.%

 

ddlgen -Usa -P -SHARBOR:1955 -TI -Npubs2.%.%.%

Example 13

Keys – Both of these generate DDL for the primary and unique keys of all the tables in a database that begin with “PK”:

ddlgen -Usa -P -TKC -Ndbname .%.%.PK%

Or:

ddlgen -Usa -P -TKC -N%.%.PK% -Ddbname

Example 14

Logical keys LK generates logical keys of table defined by sp_primarykey , sp_commonkey , sp_foreignkey statements. Since these keys do not have a name, the name of the object in this case would be the name of the table. This example generate a DDL for logical keys of table authors in database pubs2 running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TLK -Npubs2.dbo.authors

To generate DDL for all logical keys in database pub2 use:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TLK -Npubs2.%.%

To filter out logical keys definition from DDL of table authors use LK in -F argument, use:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TLK -Npubs2.dbo.authors -FLK

Example 15

Logins – Generates DDL for all logins on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TL -N%

The password in the DDL generated for all logins is “password”.

Alternatively, you can specify an individual login by using -Nusername instead of -N% :

ddlgen -Ulogin -Ppassword -Sserver :port -TL -Nusername

Example 16

Remote Servers – Generates DDL for a remote server called ORANGE on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TRS -NORANGE

To generate DDL for all remote servers:

ddlgen -Ulogin -Ppassword -Sserver :port -TRS -N%

Example 17

Roles – Generates DDL for the sa _ role on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TRO -Nsa_role

To generate DDL for all roles:

ddlgen -Ulogin -Ppassword -Sserver :port -TRO -N%

The password in the DDL generated for all roles is “password”.

Example 18

Rules – Generates DDL for all rules associated with authors on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TR -Nauthors.dbo.%

The % symbol tells ddlgen to create DDLs for all rules that exist on the server.

You can also give the fully qualified name of the rule:

ddlgen -Ulogin -Ppassword -Sserver :port -TR -Ndbname .owner .rulename

Alternatively, you can also use the -D parameter:

ddlgen -Ulogin -Ppassword -Sserver :port -TR -Nowner .rulename -Ddbname

Example 19

Segments – Generates DDL using the fully qualified dbname .segmentname format in the -N option for a segment called logsegment for the pubs2 database, on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TSGM -Npubs2.logsegment

Alternatively, you can use specify the dbname using the -D option:

ddlgen -Ulogin -Ppassword -Sserver :port -TSGM -Nsegmentname -Ddbname

To generate DDL for all segments:

ddlgen -Ulogin -Ppassword -Sserver :port -TSGM -Ndbname .%

Example 20

SQLJ functions – Generates DDL for a SQLJ function named region _ of owned by dbo in database master :

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TF –Nmaster.dbo.region_of

Alternatively you can also use the -D parameter:

ddlgen -Ulogin -Ppassword -Sserver :port -TF –Ndbo.region_of –Dmaster

To generate DDL for all SQLJ functions in a database, use object type F :

ddlgen -Ulogin -Ppassword -Sserver :port -TF –Ndbname .owner .%

Example 21

SQLJ procedures – are a kind of stored procedure. You generate DDL for SQL procedures along with DDL for stored procedures. The following generates DDL for all stored procedures—including SQLJ procedures—owned by dbo in the master database:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TP –Nmaster.dbo.%

To generate DDL for all SQLJ procedures that are only owned by dbo in the master database, use the following, where the extended type OD refers to SQLJ procedures:

ddlgen -Ulogin -Ppassword -Sserver :port -TP –Nmaster.dbo.% -XOD

To generate DDL for all procedures except SQLJ procedures owned by dbo in the master database, use the following, where the extended type OU refers to all stored procedures except SQLJ procedures:

ddlgen -Ulogin -Ppassword -Sserver :port -TP –Nmaster.dbo.% -XOU

Example 22

Stored procedures – Generates DDL for the sp_monitor stored procedure for the pubs2 database on a machine named HARBOR using port 1955, using the fully qualified dbname .owner .procedure _ name format for the -N option:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TP -Npubs2.dbo.sp_monitor

Alternatively, you can use specify the dbname using the -D option:

ddlgen -Ulogin -Ppassword -Sserver :port -TP -Nowner .procedurename -Ddbname

To generate DDL for all stored procedures:

ddlgen -Ulogin -Ppassword -Sserver :port -TP -Ndbname .owner .%

Example 23

Tables – Generates DDL for all user tables in the pubs2 database owned by “dbo” and running on a machine named HARBOR using port 1955:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TU -Ndbo.% -Dpubs2

You can also use the -N parameter to give the fully qualified name of the table:

ddlgen -Ulogin -Ppassword -Sserver :port -TU

    -Ndbname .tableowner .tablename

Alternatively, you can also use the -D parameter to specify the database:

ddlgen -Ulogin -Ppassword -Sserver :port -TU

    -Ntableowner .tablename -Ddbname

To generate DDL for all proxy tables, which uses the value OD , use -XOD instead, where X is the extended type, and OD denotes proxy tables:

ddlgen -Ulogin -Ppassword -Sserver :port -TU

    -Ntableowner .% -Ddbname -XOD

To generate DDL for all user tables, which uses the value OU , use -XOU instead, where X is the extended type, and OU denotes user tables:

ddlgen -Ulogin -Ppassword -Sserver :port -TU

    -Ntableowner .% -Ddbname -XOU

To generate DDL for all tables, including user tables and proxy tables:

ddlgen -Ulogin -Ppassword -Sserver :port -TU -Ndbname .tableowner .%

Example 24

Triggers – Generates DDL for the trigger checksum for the pubs2 database on a machine named HARBOR using port 1955, using the fully qualified dbname .owner .trigger _ name format for the -N option:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TTR -Npubs2.dbo.checksum

Alternatively, you can use specify the database _ name using the -D option:

ddlgen -Ulogin -Ppassword -Sserver :port -TTR

    -Nowner .triggername -Ddbname

To generate DDL for all triggers:

ddlgen -Ulogin -Ppassword -Sserver :port -TTR -Ndbname .owner .%

 

Example 25

User-defined datatypes – Generates DDL for the user-defined datatype “Identype” for the pubs2 database on a machine named HARBOR using port 1955 using the fully qualified dbname .userdefined _ datatype format for the -N option:

ddlgen -Uroy -Proy123 -SHARBOR:1955 -TUDD -Npubs2.Identype

Alternatively, you can use the -D option to specify the dbname :

ddlgen -Ulogin -Ppassword -Sserver :port -TUDD

    -Nuserdefined_datatype -Ddbname

To generate DDL for all user-defined datatypes:

ddlgen -Ulogin -Ppassword -Sserver :port -TUDD -Nbname .%

For example, this generates DDL for all indexes for all tables in the pubs2 database Usage


ddlgen does not identify existing sequences within views, stored procedures or triggers. For this reason, when generating DDL for a database, you must first run ddlgen on those views, stored procedures and triggers that are independent, before running ddlgen on those with dependencies. For example, if view B depends on view A, you must first run ddlgen on view A, before running it on view B.


The default information for ddlgen is:

 

 

Option  Parameter  Required  Default 
-U  username  Yes None
-P  password  Yes None
-S  host _ name :port _ number  Yes None
-T  object _ type  No Database
       
  See the -T parameter description for a list of valid object types    
-N  object _ name  Yes, if object _ type for -T is not DB (database) Default database name of username , if -Tobject _ type is db or if -T is not specified
-D  database _ name  No Default database of username 
-X  extended _ object _ type  No; use only when the object _ type for -T is U (user table), P (procedure), DB (database) None
       
  Options are:    
       
  o    
  OU – for user tables, user databases (excluding temporary databases), and stored procedures (excluding SQLJ procedures).    
       
  o    
  OD – for proxy tables, temporary databases, and SQLJ procedures.    
-O  output _ file _ name  No Standard out
-E  error _ file _ name  No Standard out
-L  log _ file _ name  No None
-V  version _ number of ddlgen  No None

 

 

At the command line, invoke ddlgen using the ddlgen shell script file ( ddlgen.bat for Windows), included in your Adaptive Server installation. The main class in DDLGen.jar is com.sybase.ddlgen.DDLGenerator .


To start ddlgen in the Sybase Central plug-in for Adaptive Server:

a.Right-click on the object for which you want to generate DDL.

b.Select Generate DDL .


In the output DDL of create table , bind statements are generated as independent DLL instead of dependent DLL.

 

Filters

If you use an invalid filter parameter, ddlgen generates a warning, ignores that parameter, and continues with the rest of the valid parameters you specify.

If you specify % along with other filter parameters, ddlgen ignores all other filterable parameters, and only shows schema-only definitions. ddlgen then continues to evaluate the dependencies within the subset of the applied as the filterable parameters for the database.

Permissions

Since ddlgen needs to obtain data from system catalogs, users must either be logged in as “dbo” or have select permissions on syscatalogs .

————————————————————————————————-
—- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
—- 转载务必注明原始出处 : http://www.dbainfo.net
—- 关键字:ddlgen 表结构
————————————————————————————————-

  • 本文链接地址:http://www.dbainfo.net/sybase-ase-get-object-ddl-with-ddlgen.htm
  • 本文为dbainfo个人原创,请在尊重作者劳动成果的前提下进行转载;
  • 转载务必注明原始出处 : Sybase数据库技术,数据库恢复专家
  • 对《用DDLGEN从ASE数据库中提取对象的定义语法》有何疑问或见解,请在本文下方发表;
  • 对网站还有其他问题或建议,请提交在留言板,谢谢!
  • 目前还没有任何评论.
    :wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)