Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-integrating-lotus-quickplacequickr-ibm-lotus-notes-and-domino-851
Packt
05 Feb 2010
7 min read
Save for later

Integrating Lotus QuickPlace/Quickr with IBM Lotus Notes and Domino 8.5.1

Packt
05 Feb 2010
7 min read
The Lotus brand within the IBM Software group represents the "people facing" side of the overall IBM product family. This does not necessarily mean the end user uses no other IBM products, but the Lotus brand is the front end of the IBM SOA  Interaction Services component. The following diagram shows the interaction between these components. Each can be deployed as a separate infrastructure piece and provide value. However, when  they are leveraged as an integrated solution, the possibilities are nearly endless. WebSphere Portal Server provides an on-the-glass integration solution for your enterprise. It allows you to create composite role-based applications from different data sources. For more information, visit http://www.ibm.com/websphere/portal Web Content Management is now an integrated piece of the WebSphere Portal Server. It provides an end user driven content authoring and content delivery system. Visit http://www.ibm.com/websphere/portal Lotus Notes/Domino is IBM's fagship messaging and collaboration product, deployed to over 100 million users. It provides a foundation on which many of the other value-added products build. Visit http://www.ibm.com/software/sw-lotus/products/product4.nsf/wdocs/dominohomepage Lotus QuickPlace/Quickr is IBM's team collaboration product. It provides template-based services and a set of content connectors, allowing end users to quickly create interactive team places, all without the need for administrator intervention. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/ltwhome Lotus Sametime is IBM's unified communications and collaboration product. It provides enterprise-class instant messaging and web conferencing services, as well as a platform for many other capabilities. This includes telephony and voice integration services. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/st75home Lotus Connections is IBM's "social networking" product. It provides a new category of integrated application services covering the following areas: activities, dogear, blogs, communities, and profles. Visit http://www.ibm.com/software/sw-lotus/products/product3.nsf/wdocs/connections This article does not cover all the products available under the Lotus brand. For additional information on these, visit http://www.lotus.com Lotus QuickPlace/Quickr The Lotus QuickPlace product has been available for several years. QuickPlace has become recognized as a leader in web-based team collaboration, and it is used in many large corporations throughout the world. In early 2007, IBM announced two important changes to the QuickPlace product family: The new version of Lotus QuickPlace will be renamed Lotus Quickr A new J2EE-based version of QuickPlace will be introduced, also called Lotus Quickr These two versions of Quickr (one based on Domino and one based on WebSphere Portal) form a single product. They do, however, have very different deployment architectures. From an end user's standpoint, they should be viewed as collaboration appliances. They will be presented with a consolidated list of places where they  are involved so that the end users can easily navigate. This will be the case regardless of the backend deployment architecture. The goal of these changes to QuickPlace/Quickr is simplification. IBM wants the product to be so simple that an end user can, with a few clicks, generate productive services. There is also a focus on server deployment simplification. One of the key components of Quickr is the connector technology that it introduces. These connectors will allow for direct and programmatic interaction with the data stored in the Quickr places. Connectors that will be shipping with Quickr 8.0 are the following: Notes Sametime File System/Windows Explorer RSS/ATOM In this section, we will cover each edition and discuss how it integrates with Domino. We will not be covering how to install the product itself; this is covered in detail within the product documentation. Quickr with services for Domino The Domino-based edition of Quickr should be thought of as a signifcant upgrade to the existing QuickPlace product line. This product has been maturing over many years, and this new release provides many new capabilities. These include native support for wikis and blogs "out of the box". Installing Lotus Quickr The basic installation process for Quickr with service for Domino is very simple. It involves installing a base Domino server v7.0.2 FP1. The Quickr product components are then installed on top of this server. Directory integration After installation, there is some additional configuration required, depending on the intended usage. They are: User/group directory configuration is used to control the authorization and authentication of the environment Sametime integration is used to enable presence awareness within the places QPServlet confguration is used for WebSphere Portal integration The user/group directory configuration allows you to select one of three directory types: Internal place level directory allows for registration of users at a place level. The users are independent of any corporate directory that may be in place. Generally this is used to support external user access. Lotus Domino Directory allows users and groups to be stored in the names.nsf database (public address book) and corresponding directories surfaced via directory assistance. LDAP directory allows for users in a supported native LDAP directory (for example, Domino, IBM Tivoli Directory Server, Microsoft Active Directory, Novelle Directory, or Sun One Directory). This configuration allows for the refinement of the settings used to interact with the LDAP source. The directory can be configured by first logging as an administrative user. In the following screenshot, we have logged in as user in Admin from the Domino Directory. Next, select the User Directory option from Site Administration. The following screen shows the default value of No Directory selected. This is the base setup where the contacts.nsf database for each place will be used as a user directory. It is possible to change the user directory by clicking the Change Directory button. This lets you choose between No Directory, LDAP Server, and Domino Server. If LDAP Server is selected, then options for connecting to the directory server will be displayed, as shown in the following screenshot: This screen contains the following felds: Name provides the host name of the LDAP Directory Server. Port number is the LDAP TCP/IP port used to communicate with the server. Check for SSL connection with LDAP User Directory enables SSL  encryption of the LDAP traffic. Note that this is an "all or nothing" selection. It is not possible to only encrypt parts of the conversation with the  LDAP server. Search base controls determines where in the LDAP tree to search for users and groups. For a Domino LDAP directory this value is generally left blank. This is because groups in Domino, as seen through LDAP, have no organizational component (for example, cn=Sales Users). Narrow searches to the place name further restricts the LDAP search to users that contain the Quickr place name (for instance, Sales). Check to use credentials specified below when searching the directory controls whether or not anonymous access is used for the LDAP directory. It is very common to have read-only binding credentials to search the directory. Username provides the user's distinguished Name for the LDAP server (for example, cn=quickrbind, ou=Admin, o=Acme). Password is the password for the username above. Authentication Timeout controls the time in seconds for the login operation to timeout. The default is 120 seconds. Search Timeout controls the time in seconds for LDAP searches to timeout. The default is 120 seconds.
Read more
  • 0
  • 0
  • 8345

article-image-new-features-domino-designer-85
Packt
05 Feb 2010
7 min read
Save for later

New features in Domino Designer 8.5

Packt
05 Feb 2010
7 min read
There are many exciting changes and additions to Domino Designer 8.5. We will begin with the introduction of the Eclipse based integrated development environment. Domino Designer 8.5, which is also known as Domino Designer on Eclipse or DDE, takes advantage of Eclipse technology to deliver a more powerful developer environment. The look and feel is more consistent with Notes client version 8.x. The new UI will be examined at a high level. The next major feature addition that will be covered is XPages. XPages are a new type of design element being introduced in the 8.5 release that will revolutionize Domino Web Applications. XPages enable application developers to quickly and easily create rich Domino web applications with a Web 2.0 look and feel. Finally, we will review improvements to CSS support, enhancements to HTML generation, JavaScript controls, a new method related to ID Vault: ResetUserPassword, and changes to web services. Domino Designer on Eclipse Now in 8.5 the Domino Designer client is based on Eclipse, as the Notes client was in 8.x. Eclipse is an award-winning, open source platform for the construction of powerful software development tools and rich desktop applications. This architectural change allows the new designer client to become an open source pluggable environment. By allowing the use of plugins, objects can be built, re-used, and shared. Some of the differences in the new 8.5 Designer client can be seen when examining the processes associated with Domino Designer. It is useful to know how they relate to one another and what component each controls. Prior to release 8.5 designer clients, when you launched designer.exe, nlnotes.exe would be spawned. This is the process in which pre-8.5 Domino Designer ran. Now in the 8.5 Designer client, designer.exe loads and spawns nlnotes.exe. On faster machines, designer.exe shows up briefly, and may not be seen at all. Then the notes2.exe process spawns and designer.exe quits. notes2.exe is the Java process that corresponds to the Eclipse shell. Finally, nlnotes.exe spawns ntaskldr.exe after DDE opens. Some other things you may notice are that launch and exit take longer than in previous versions. This is due to the Eclipse startup and shutdown sequences. This can lead to problems on exit or launch. If you experience a problem with launch or exit, it may be due to one of the following issues. Due to the longer exit time, the user may have initiated launch before all prior processes had been killed, or the user may have initiated the launch sequence multiple times. It is also possible that, on prior exit, the client did not shut down all processes. With a few exceptions, the launch process will be able to compensate for these errors. However, if you still can't launch or exit the 8.5 designer client, you can try the following, manually. Kill the nlnotes.exe and notes2.exe processes with the task manager, or if the client still will not launch or exit, log off the system to completely kill all process threads. The new Eclipse-based GUI Now that the 8.5 Designer client is Eclipse based, there is a new UI. The default perspective in 8.5 is the Domino Designer perspective. There are other perspectives available in Domino Designer 8.5, each suited to a particular task. You can select a different perspective from the menu, select Window | Open Perspective | Other, as seen in the following screenshot: Not all perspectives have a corresponding layout in the UI. Perspectives can be customized to suit individual preferences. One way is by resizing the views and editors. You can resize views and editors in one of two ways. Click the Maximize/Restore button located in the title bar of the view or editor. Or, click and drag the border of a view or editor. Views and editors can also be hidden by clicking the view Close button. Use the menu pick Window | Show Eclipse Views to reopen closed views. You can use this menu pick to open any Eclipse view, including those from other perspectives. To return to the current perspective's default layout use the menu pick Window | Reset Perspective.... XPages For a while now it has been difficult to create elegant web applications for Notes/Domino. XPages are a new type of design element being introduced in the 8.5 release, that will allow application developers to quickly and easily create rich Domino web applications with a Web 2.0 look and feel. Applications built using XPages are supported for web use only, for the 8.5 release. To enhance the appearance and functionality for web use, existing applications can be extended to utilize XPages. The standard design elements must be included in the database for use in the Notes client and the application. If a new application is targeted for both Notes client and web users, then you can also include XPages for use on the Web. XPages are built on top of JSF, or Java Server Faces, technology. XPages also have built-in Ajax support, which allows application developers to take advantage of Ajax features such as type-ahead and partial page refresh. They are created in pure XML markup. When the application developer adds controls to XPages using drag and drop, the XML is generated automatically. XPages does not require any additional steps to install on a Domino server. When you create a new XPage in an application, you start with a blank page similar to what you see when a new form or page is created. You then build the XPage by dragging and dropping controls onto the XPage to add functionality. A wide array of controls is available out of the box, which enables application developers to quickly and easily get a web application up and running. Some examples of the controls available are a pager, rich text editor, date picker, tabbed panel, and many more. Controls can also be combined into a single object, called a custom control. Custom controls are similar to sub-forms, as they can be used in other XPages in the current application or copied into other applications for reuse. Just like with sub-forms, if a change is made to a custom control in an application, that change is propagated out to all other instances of that custom control in that application. There is a default system template in the 8.5 release that uses XPages. The discussion template has been enhanced to include XPages in 8.5. Improvements to CSS Support Now in Domino Designer 8.5 you can edit and create CSS. Previously, you would have to use an external editor to do this. Not only can you create custom stylesheets, but you can import existing ones. You can also group your favorite stylesheets and script resources into a theme to provide a common look and feel in your application and map style classes to UI controls. This will save developer time and effort when adding CSS to applications. To create a new stylesheet: Click File | New | Style Sheet Resource from the main Eclipse menu. In the New Style Sheet dialog box, do the following: In the Name field, type the name of the stylesheet. By default, Domino Designer adds a CSS file extension to this name In the Application field, select an application for the stylesheet. Click OK Another method of creating a stylesheet, is by double-clicking Resources | Style Sheets in the Applications navigator and then clicking New Style Sheet in the editor.
Read more
  • 0
  • 0
  • 8149

article-image-n-way-replication-oracle-11g-streams-part-1
Packt
05 Feb 2010
4 min read
Save for later

N-Way Replication in Oracle 11g Streams: Part 1

Packt
05 Feb 2010
4 min read
N-way replication refers to a Streams environment where there are multiple sources. In this article, we will still use the STRM1 and STRM2 databases but with a little twist; making both databases the source. By making both STRM1 and STRM2 sources, we need to first consider a couple of unique situations and do a little more pre-planning, specifically for N-Way replication. The concepts and techniques used to configure a 2-way replication can then be used to scale to N-way replication. We all need to crawl before we run, the better you crawl (understand) this article, the easier it will be to scale up to N-way replication. Pay close attention and learn the technique so that you can implement it well. We need to repeat this—Streams is not Failover. We need to repeat this—Streams is not Failover. No, that is not a typo. The authors are passionate about Streams and want to see you successfully implement it. To successfully implement Streams, you need to know not to step into the trap of using it for Failover. Both authors have done some work where Failover was the requirement. Streams is not a Failover solution. Failover is handled by Oracle Data Guard, NOT Oracle Streams. Streams is about distributing the data to multiple locations. On more than one occasion, Streams was used as a Failover technology because it can distribute data to multiple locations. Do not fall into the trap of using the wrong tool for the wrong job. Streams distributes (replicates) data. As such, there will always be some difference between the databases in a Streams environment. All replication technology has this problem. The only time where all of the databases are in sync is, when there is no activity and all replication has been applied to all target locations. If you need Failover, then use the proper tool. Oracle Data Guard is for Failover. It has the necessary processes to guarantee a different level of failover from a primary site to a secondary site, whereas Streams is a Replication tool that distributes data. Just remember the following, when there is a discussion of Replication and Failover that comes up: Streams distributes data, it is built for replication Data Guard is built for Failover Pre-planning for N-way replication When we set up N-way replication, we must consider the possibility of a collision of data. Since we have multiple sources of data, it is possible for the exact same data to be inputted on any or all of the sources at the exact same time. When this happens, it is a conflict. This example is just one type of conflict that can happen in N-way replication environments. The types of conflict that can occur are as follows: Update conflict: When transactions from different databases try to update the same row at nearly the same time. Delete conflict: When one transaction deletes a row and the next transaction tries to update or delete the row. Transactions originate from different databases. Unique conflict: When transactions from different databases violate a primary or unique constraint, the first transaction is accepted. The second transaction obtains the conflict. Foreign key conflict : This happens when a transaction from a Source tries to insert a child record before the parent record exists. The good news is that Oracle has provided built-in conflict resolution in Streams that solves the most common situations. The built-in solutions are as follows: OVERWRITE DISCARD MAXIMUM MINIMUM We will provide an example of conflict resolution after we build our N-way replication. In our case, we will use MAXIMUM. As part of the pre-planning for N-way replication, we highly suggest creating a simple table such as the Setup Table. Avoiding Conflict As conflict requires additional pre-planning and configuration, one begins to wonder, "Are there techniques so that we can configure N-way replication without the possibility of conflict?" The simple answer to the question is "Yes". The not-so simple answer is that there is some configuration magic that needs to be done and the devil is in the details. Limiting who and what can be updated is one method of avoiding conflict. Think of it this way— there is no conflict if we agree to who and what can update the specific data. User 1 can only update his specific data and no one else can do that. Similarly, user 2 can only update his specific data. So, user 1 and user 2 can never cause a conflict. Now this may be a little bit difficult depending on the application. This can be implemented with the use of offset sequences. One sequence produces only odd values, and another produces only even values. We could also use a combination of sequence and some unique characteristics of the database.
Read more
  • 0
  • 0
  • 2200

article-image-oracle-11g-streams-rules-part-2
Packt
05 Feb 2010
10 min read
Save for later

Oracle 11g Streams: RULES (Part 2)

Packt
05 Feb 2010
10 min read
Rule based transformation—eat your heart out transformers! As with all good rules, some are made to be broken; or maybe changed. In some circumstances we need to have rules that govern change. In Advance Replication, a number one rule is that a replicated table must have the same structure at all master sites. The column names and data types have to be identical or the "apply" of a deferred transaction will fail. With Streams, we can now break this rule by adding a new rule that allows the LCR to "morph" to a new structure. We call this ability Rule Based Transformation; and it is done via complex rules and action context. When you plan your Rule Based Transformation design, you want to remember that Rule Based Transformation rules are only evaluated with positive Rule Sets. If the Rule Set is negative, the Rule Based Transformation is ignored. Declarative versus User Created In the real world, there are many ways to accomplish the same thing; just as there are many ways to model data. You may run into a situation where the table structure in one master database may be different from the structure of the table in another master database but data must be replicated between them. It could be that a table column at one master is a VARCHAR2, but is a DATE at another master site. Or perhaps the column does not exist at all. Rule Based Transformation provides the ability to capture the LCR and convert it to the necessary structure needed to apply it at the destination site. This is not to be confused with transformations accomplished via the DBMS_TRANSFORMATION package. That is a different fish (and doesn't swim in this stream). A special note concerning SUBSET Rules and transformations. A SUBSET Rule has an internal row_migration transformation assigned to it when it is created. This internal transformation will always be the first one executed before any other transformations. Another thing to keep in mind is the amount of "transformation" that will be applied to the LCR. If extensive transformations need to be made to the LCR, you may wish to consider using a custom DML handler instead to take advantage of the apply parallel capabilities. The remainder of this section is going to use the premise that we have an LCR that we need to change a column name for, before we send it out from the source site. The LCR is generated on a table which has a different column name than the corresponding table at all the other sites. This being the case, we are going to create the transformation at the Capture process. There are two ways to accomplish this; either by using a declarative transformation or a user created transformation. We will review each, and then apply the method to our LCR that needs a column name change. Depending on the Transformation type, you can use one of the following views to find information concerning the transformation: Declarative: DBA_STREAMS_TRANSFORMATIONS User Created: DBA_STREAMS_TRANSFORM_FUNCTION Declarative Transformation As of 10g, Oracle provides commonly used transformations in the DBMS_STREAMS_ADM package. These transformations are referred to as declarative transformations. Declarative transformations only work with row LCR's (aka DML LCR's). The row LCR can be a Streams captured LCR (basic or synchronous), or a user created message. The procedures allow you to add transformation rules to do the following: Add a column (DBMS_STREAMS_ADM.ADD_COLUMN) Delete a column (DBMS_STREAMS_ADM.DELETE_COLUMN) Rename a column (DBMS_STREAMS_ADM.RENAME_COLUMN) Rename a table (DBMS_STREAMS_ADM.RENAME_TABLE) Rename a schema (DBMS_STREAMS_ADM.RENAME_SCHEMA) Special considerations when DBMS_STREAMS_ADM.ADD_COLUMN Be aware that the DBMS_STREAMS_ADM.ADD_COLUMN procedure does not support a number of data types. These include: LOBS (BLOB, CLOB, NCLOB, BFILE, and so on) LONG, LONG RAW, and so on ROWID User-defined types (including object types, REFs, varrays, nested tables, and so on) Oracle-supplied types (including ANY types, XML types, spatial types, and media types) For more information on DBMS_STREAMS_ADM Declarative Transformation subprograms, please refer to the Oracle Database PL/SQL Packages and Types Reference. For our purposes, we want to use the DBMS_STREAMS_ADM.RENAME_COLUMN to create a declarative transformation. In our example, we will work with the JOB_HISTORY table from the Oracle Example HR Schema. We will assume that at our source database the HR.JOB_HISTORY table has a column named DEPARTMENT_ID, and at the destination database the corresponding column in the HR.JOB_HISTORY is DEPT_ID. Declarative Transformations can only be added to an existing rule. If the rules specifi ed do not exist, an error is raised. Also, the transformation will be owned by STRM_ADMIN so make sure you have explicitly granted all privileges on HR.JOB_HISTORY to STRM_ADMIN. First we find the rule to which we wish to add the declarative transformation, logged in as STRM_ADMIN we can look at the USER_RULES view: SQL> select * from user_rules;RULE_NAME------------------------------RULE_CONDITION-------------------------------------RULE_EVALUATION_CONTEXT_OWNER RULE_EVALUATION_CONTEXT_NAME------------------------------ ------------------------------RULE_ACTION_CONTEXT(ACTX_LIST(NVN_NAME, NVN_VALUE()))--------------------------------------------------------------RULE_COMMENT--------------------------------------------------------------HR1((:dml.get_object_owner() = 'HR') and :dml.get_source_database_name()= 'STRM1')SYS STREAMS$_EVALUATION_CONTEXTHR2((:ddl.get_object_owner() = 'HR' or :ddl.get_base_table_owner() ='HR') and :ddl.get_source_database_name() = 'STRM1' )SYS STREAMS$_EVALUATION_CONTEXT HR1 is our Row LCR (:dml) rule, so we will add To create our declarative transformation Rule, we issue the following command: beginDBMS_STREAMS_ADM.RENAME_COLUMN(rule_name => 'strm_admin.HR1',table_name => 'HR.JOB_HISTORY',from_column_name => 'DEPARTMENT_ID',to_column_name => 'DEPT_ID',value_type => '*', -- defaultstep_number => 0, --defaultoperation => 'ADD' -–default);end;/ We can now check the rule in the USER_RULES view: SQL> select * from user_rules where rule_name = 'HR1';RULE_NAME------------------------------RULE_CONDITION-------------------------------------------------------------RULE_EVALUATION_CONTEXT_OWNER RULE_EVALUATION_CONTEXT_NAME------------------------------ ------------------------------RULE_ACTION_CONTEXT(ACTX_LIST(NVN_NAME, NVN_VALUE()))-------------------------------------------------------------RULE_COMMENT-------------------------------------------------------------HR1((:dml.get_object_owner() = 'HR') and :dml.get_source_database_name()= 'STRM1')SYS STREAMS$_EVALUATION_CONTEXTRE$NV_LIST(RE$NV_ARRAY(RE$NV_NODE('STREAMS$_INTERNAL_TRANS',ANYDATA()))) Notice that the RULE_COMMENT now has an entry indicating the inclusion of the transformation rule. We can also look at the DBA_STREAMS_TRANSFORMATION view: SQL> select rule_owner, rule_name, transform_type,2 from_column_name, to_column_name, value_type,3 declarative_type, precedence, step_number4 from dba_streams_transformations;RULE_OWNER------------------------------RULE_NAME TRANSFORM_TYPE------------------------------ --------------------------FROM_COLUMN_NAME TO_COLUMN_NAME VAL-------------------- -------------------- ---DECLARATIVE_TYPE PRECEDENCE STEP_NUMBER-------------------- ---------- -----------STRM_ADMINHR1 DECLARATIVE TRANSFORMATIONDEPARTMENT_ID DEPT_ID *RENAME COLUMN 2 0 To remove the declarative transformation from the rule, we use the same procedure we used to create the transformation, but set the operation parameter to REMOVE: beginDBMS_STREAMS_ADM.RENAME_COLUMN(rule_name => 'strm_admin.HR1',table_name => 'HR.JOB_HISTORY',from_column_name => 'DEPARTMENT_ID',to_column_name => 'DEPT_ID',operation => 'REMOVE' -–default);end;/ Note: Removing the declarative transformation does not clear the RULE_COMMENT we see in the USER_RULES view. However, it does clear the entry from the DBA_STREAMS_TRANSFORMATION view . For more detailed information on using the DBMS_STREAMS_ADM.RENAME_COLUMN, and other declarative transformation procedures, please refer to the Oracle PL/SQL Packages and Types Reference, and the Oracle Streams Concepts and Administration Guide. User Created Rule Based Transformations (UCRBT) You can also create your own Rule Based Transformations. These transformations are referred to as user-created transformations (imagine that). The steps for creating a UCRBT are pretty basic. Create the PL/SQL function that performs the transformation. The function should receive the LCR as a SYS.ANYDATA IN parameter The function should return either an LCR a SYS.ANYDATA or STREAMS$_ANYDATA_ARRAY If the function returns a STREAMS$_ANYDATA_ARRAY, it can only be associated with a capture rule Grant the EXECUTE privilege on the function to the appropriate user as necessary. Create or locate the rules for which the transformation will be used. Set the custom rule-based transformation for each rule by running the SET_RULE_TRANSFORM_FUNCTION procedure. In this example, we will setup a UCRBT that makes the same transformation as the previous declarative transformation. The UCRBT is going to be owned by STRM_ADMIN so make sure you have explicitly granted all privileges on HR.JOB_HISTORY to STRM_ADMIN. The code for this example can be found in the UCRBT.sql code file. First we create the PL/SQL function to accomplish the transformation; STRM_ADMIN will be the function owner, so make sure you are logged in as STRM_ADMIN in this example: CREATE OR REPLACE FUNCTION DEPT_COLNAME_CHANGE (evt IN SYS.AnyData)RETURN SYS.AnyData ISlcr SYS.LCR$_ROW_RECORD;obj_name VARCHAR2(30);rc NUMBER;BEGINIF evt.GetTypeName='SYS.LCR$_ROW_RECORD' THENrc := evt.getObject(lcr);obj_name := lcr.GET_OBJECT_NAME();IF obj_name = 'JOB_HISTORY' THENlcr.RENAME_COLUMN('DEPARTMENT_ID','DEPT_ID','*');RETURN SYS.ANYDATA.ConvertObject(lcr);END IF;END IF;RETURN evt;END;/ Because STRM_ADMIN is the function owner, we do not need to grant EXECUTE on the function. If the function was created in a different schema, then we would want to explicitly grant execute on the function to STRM_ADMIN. Next we determine which rule to which to add the transformation function. You can either create a new rule at this point, or use an existing rule. We will use our HR1 rule from above (we can do this because we removed the Declarative RENAME_COLUMN transformation from the rule in our last step of the Declarative Transformation example). select * from dba_rules; Then, we use the DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION procedure to add the transformation function to the desired rule: BEGINDBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(rule_name => 'HR1',transform_function => 'strm_admin.DEPT_COLNAME_CHANGE');END;/ We will now see the transformation in the DBA/ALL_STREAMS_TRANSFORM_FUNCTION view: SQL> select * from all_streams_transform_function;RULE_OWNER------------------------------RULE_NAME VALUE_TYPE------------------------------ --------------------TRANSFORM_FUNCTION_NAME CUSTOM_TYPE----------------------------------- -----------STRM_ADMINHR1 SYS.VARCHAR2"STRM_ADMIN"."DEPT_COLNAME_CHANGE" ONE TO ONE For more detailed information on UCRBT, please reference the Usage Notes for the DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION procedure in the Oracle PL/SQL Packages and Types Reference, and the Oracle Streams Concepts and Administration Guide. Transformation Order of Execution It is possible to have a combination of declarative and user defined transformations assigned to a single rule. This being the case, how do you know which ones get executed when? Especially, if you have not assigned step numbers. There is a default order of execution for transformation that help keep the rule from running amuck. If the rule is a Subset rule, then Row Migration is always executed first Next are Declarative Rule based transformations These are further ordered by the step number specified for each transformation if they have been assigned. If the step numbers are not assigned, the transformations are executed in the following order: Delete_Column Rename_Column Add_Column Rename_Table Rename_Schema Last (but not the least), the User Created Rule-Based Transformation is executed.
Read more
  • 0
  • 0
  • 2702

article-image-n-way-replication-oracle-11g-streams-part-2
Packt
05 Feb 2010
7 min read
Save for later

N-Way Replication in Oracle 11g Streams: Part 2

Packt
05 Feb 2010
7 min read
Streaming STRM2 to STRM1 Now the plan for setting up Streams for STRM2. It is the mirror image of what we have done above, except for the test part. On STRM2, log in as STRM_ADMIN. -- ADD THE QUEUE, a good queue name is STREAMS_CAPTURE_Q -- ADD THE CAPTURE RULE -- ADD THE PROPAGATION RULE -- INSTANTIATE TABLE ACROSS DBLINK -- DBLINK TO DESTINATION is STRM1.US.APGTECH.COM -- SOURCE is STRM2.US.APGTECH.COM On STRM1 log in as STRM_ADMIN. -- ADD THE QUEUE: A good queue name is STREAMS_APPLY_Q -- ADD THE APPLY RULE Start everything up and test the Stream on STRM2. Then check to see if the record is STREAM'ed to STRM1. -- On STRM2 log in as STRM_ADMIN -- ADD THE QUEUE :A good queue name is STREAMS_CAPTURE_Q -- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.SET_UP_QUEUE(queue_table => '"STREAMS_CAPTURE_QT"',queue_name => '"STREAMS_CAPTURE_Q"',queue_user => '"STRM_ADMIN"');END;/commit;-- ADD THE CAPTURE RULE-- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_type => 'capture',streams_name => '"STREAMS_CAPTURE"',queue_name => '"STRM_ADMIN"."STREAMS_CAPTURE_Q"',include_dml => true,include_ddl => true,include_tagged_lcr => false,inclusion_rule => true);END;/commit;-- ADD THE PROPAGATION RULE-- STRM_ADMIN@STRM2.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_name => '"STREAMS_PROPAGATION"',source_queue_name =>'"STRM_ADMIN"."STREAMS_CAPTURE_Q"',destination_queue_name =>'"STRM_ADMIN"."STREAMS_APPLY_Q"@STRM1.US.APGTECH.COM',include_dml => true,include_ddl => true,source_database => 'STRM2.US.APGTECH.COM',inclusion_rule => true);END;/COMMIT; Because the table was instantiated from STRM1 already, you can skip this step. -- INSTANTIATE TABLE ACROSS DBLINK-- STRM_ADMIN@STRM2.US.APGTECH.COM>DECLAREiscn NUMBER; -- Variable to hold instantiation SCN valueBEGINiscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@STRM1.US.APGTECH.COM(source_object_name => 'LEARNING.EMPLOYEES',source_database_name => 'STRM1.US.APGTECH.COM',instantiation_scn => iscn);END;/COMMIT; -- On STRM1, log in as STRM_ADMIN. -- ADD THE QUEUE, a good queue name is STREAMS_APPLY_Q-- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.SET_UP_QUEUE(queue_table => '"STREAMS_APPLY_QT"',queue_name => '"STREAMS_APPLY_Q"',queue_user => '"STRM_ADMIN"');END;/COMMIT;-- ADD THE APPLY RULE-- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_STREAMS_ADM.ADD_TABLE_RULES(table_name => '"LEARNING.EMPLOYEES"',streams_type => 'apply',streams_name => '"STREAMS_APPLY"',queue_name => '"STRM_ADMIN"."STREAMS_APPLY_Q"',include_dml => true,include_ddl => true,include_tagged_lcr => false,inclusion_rule => true);END;/commit; Start everything up and Test. -- STRM_ADMIN@STRM1.US.APGTECH.COM>BEGINDBMS_APPLY_ADM.SET_PARAMETER(apply_name => 'STREAMS_APPLY',parameter => 'disable_on_error',value => 'n');END;/COMMIT;-- STRM_ADMIN@STRM1.US.APGTECH.COM>DECLAREv_started number;BEGINSELECT DECODE(status, 'ENABLED', 1, 0) INTO v_startedFROM DBA_APPLY where apply_name = 'STREAMS_APPLY';if (v_started = 0) thenDBMS_APPLY_ADM.START_APPLY(apply_name => '"STREAMS_APPLY"');end if;END;/COMMIT;-- STRM_ADMIN@STRM2.US.APGTECH.COM>DECLAREv_started number;BEGINSELECT DECODE(status, 'ENABLED', 1, 0) INTO v_startedFROM DBA_CAPTURE where CAPTURE_NAME = 'STREAMS_CAPTURE';if (v_started = 0) thenDBMS_CAPTURE_ADM.START_CAPTURE(capture_name => '"STREAMS_CAPTURE"');end if;END;/ Then on STRM2: -- STRM_ADMIN@STRM2.US.APGTECH.COM>ACCEPT fname PROMPT 'Enter Your Mom's First Name:'ACCEPT lname PROMPT 'Enter Your Mom's Last Name:'Insert into LEARNING.EMPLOYEES (EMPLOYEE_ID, FIRST_NAME, LAST_NAME,TIME) Values (5, '&fname', '&lname', NULL);dbms_lock.sleep(10); --give it time to replicate Then on STRM1, search for the record. -- STRM_ADMIN@STRM1.US.APGTECH.COM>Select * from LEARNING.EMPLOYEES; We now have N-way replication. But wait, what about conflict resolution?Good catch; all of this was just to set up N-way replication. In this case, it is a 2-way replication. It will work the majority of the time; that is until there is conflict. Conflict resolution needs to be set up and in this example the supplied/built-in conflict resolution handler MAXIMUM will be used. Now, let us cause some CONFLICT! Then we will be good people and create the conflict resolution and ask for world peace while we are at it! Conflict resolution Conflict between User 1 and User 2 has happened. Unbeknown to both of them, they have both inserted the exact same row of data to the same table, at roughly the same time. User 1's insert is to the STRM1 database. User 2's insert is to the STRM2 database. Normally the transaction that arrives second will raise an error. It is most likely that the error will be some sort of primary key violation and that the transaction will fail. We do not want that to happen. We want the transaction that arrives last to "win" and be committed to the database. At this point, you may be wondering "How do I choose which conflict resolution to use?" Well, you do not get to choose, the Business Community that you support will determine the rules most of the time. They will tell you how they want conflict resolution handled. Your responsibility is to know what can be solved with built-in conflict resolutions and when you will need to create custom conflict resolution. Going back to User 1 and User 2. In this particular case, User 2's insert arrives later than User 1's insert. Now the conflict resolution is added using the DBMS_APPLY_ADM package, specifically the procedure DBMS_APPLY_ADM.SET_UPDATE_CONFLICT_ HANDLER which instructs the APPLY process on how to handle the conflict. Scripts_5_1_CR.sql shows the conflict resolution used to resolve the conflict between User 1 and User 2. Since it is part of the APPLY process, this script is run by the Streams Administrator. In our case, that would be STRM_ADMIN. This type of conflict can occur on either STRM1 or STRM2 database, so the script will be run on both databases. The numbers to the left are there for reference reasons. They are not in the provided code. -- Scripts_5_1_CR.sql1. DECLARE2. cols DBMS_UTILITY.NAME_ARRAY;3. BEGIN4. cols(0) := 'employee_id';5. cols(1) := 'first_name';6. cols(2) := 'last_name';7. cols(3) := 'time';8. DBMS_APPLY_ADM.SET_UPDATE_CONFLICT_HANDLER(9. object_name => 'learning.employees',10. method_name => 'MAXIMUM',11. resolution_column => 'time',12. column_list => cols);13. END;14. /15. Commit; So what do these 15 magical lines do to resolve conflict?Let us break it down piece by piece logically first, and look at the specific syntax of the code. Oracle needs to know where to look when a conflict happens. In our example, that is the learning.employees table. Furthermore, Oracle needs more than just the table name. It needs to know what columns are involved. Line 9 informs Oracle of the table. Lines 1 -7 relate to the columns. Line 8 is the actual procedure name. What Oracle is supposed to do when this conflict happens, is answered by Line 10. Line 10 instructs Oracle to take the MAXIMUM of the resolution_column and use that to resolve the conflict. Since our resolution column is time, the last transaction to arrive is the "winner" and is applied.
Read more
  • 0
  • 0
  • 1641

article-image-rendering-images-typo3-43-part-2
Packt
03 Feb 2010
4 min read
Save for later

Rendering Images in TYPO3 4.3: Part 2

Packt
03 Feb 2010
4 min read
Rendering links to files using <media> tags Imagine, for a second, a dark world of web development without content management systems. You have a simple website with some text and links to files to be downloaded. Now, imagine that you need to move the files into a different folder. You would have to go through each page, and update the links to point to the new location of the file. In DAM, the physical file is separate from the record describing the file. Thanks to this separation, the pages can link to the DAM record, instead of the physical file. If the file is moved, only the DAM record will need to be updated (which happens automatically if you move the file within DAM modules), and all links will automatically update. We will now explore how the <media> HTML tag can be used to take advantage of this feature. Getting Ready Make sure both DAM and htmlArea RTE extensions are installed. In the Extension Manager click on the DAM extension to get an overview of enable configuration. Make sure that the media tag option is enabled. How to do it... Create a new Regular text element on a page. Enter the HTML mode in the RTE: Type in <media 1234>Link text</media>, replacing 1234 with the UID of the DAM record, and link the text with the text you want to appear inside the link. You can find the UID of the record in the information panel. Save and preview. How it works... The advantage of the <media> tag is that instead of linking to a file, you're linking to a DAM record. The record, in turn, points to the physical file—so if you move the files around, all links will be updated automatically. There's more It may be possible that after enabling all the options in the Extension Manager, the <media> tags are encoded by RTE, and appear in the frontend unparsed. In that case, you need to enter the following options in Page TSconfig: // Add txdam_media to RTE processing rulesRTE.default.proc.overruleMode = ts_css,txdam_media // Use same RTE processing rules in FERTE.default.FE.proc.overruleMode = ts_css,txdam_media // RTE processing rules for bodytext column of tt_content tableRTE.config.tt_content.bodytext.proc.overruleMode = ts_css,txdam_mediaRTE.config.tt_content.bodytext.types.text.proc.overruleMode = ts_css,txdam_mediaRTE.config.tt_content.bodytext.types.textpic.proc.overruleMode = ts_css,txdam_media Accessing Page TSconfig To access Page TSconfig, right-click on a page in the page tree, and choose Edit page properties: Alternatively, you can browse to the page in the Page module, and click the Edit page properties button either in the module body, or in the docheader —the bar across the top of the module housing the control buttons. From there, the Page TSConfig, is available under the Options tab: Creating a gallery using ce_gallery There are multiple galleries available for TYPO3. Each has its own advantages, and an entire book can be dedicated to comparing the various extensions. We will install and configure only one as an example. ce_gallery has an advantage that it is very easy to set up and customize, and relies completely on DAM for content and organization. Getting Ready Make sure you have the extensions DAM and dam_catedit installed. Create a root category, and a few categories under it. Assign a few JPG images to each category How to do it... Install ce_gallery. Accept database and filesystem changes. In a template record, include the static template Photogallery (CSS) (ce_gallery). Add a Plugin content element of type Photogallery to a page. In the General tab, uncheck the Slimbox (pmkslimbox needed) checkbox. In the Categories tab, select the root category and check the box that says Recursive: Save and preview. The output should appear similar to the following screenshot: How it works... ce_gallery treats DAM categories as albums, which in turn, contain pictures. If you want to add more photos to an album, just assign them to a category, and clear cache on the page where you added the Photogallery plugin.
Read more
  • 0
  • 0
  • 1844
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-advanced-blog-management-apache-roller-40-part-1
Packt
03 Feb 2010
5 min read
Save for later

Advanced Blog Management with Apache Roller 4.0: Part 1

Packt
03 Feb 2010
5 min read
So let's get on with it. Managing group blogs Suddenly, your boss bursts into your office and shouts: "Well, let's give Roller a try for our company's blog!" And now, you have to enable group blogs in your Roller installation. Time for action – creating another user The first thing you need to do in order to enable group blogging is create another user, as shown in the following exercise: Open your web browser and type your Roller's dynamic hostname in the Address bar (for example, mine is http://alromero.no-ip.org). Now click on the Login link on your weblog's main page: The Welcome to Roller page will appear. Instead of logging in, click on the Register link in order to create a new user: The New User Registration screen will show up next. Fill in the fields for your new user, as shown in the following screenshot: Click on Register User when finished. If all goes well, you'll be taken back to the Welcome to Roller screen, and the following success message will appear: Select the Click here link to continue. Type your new Username and Password, and click on the Login button. The Main Menu page will appear: Click on the Create new weblog link, under the Actions panel. Roller will take you to the Create Weblog page. Fill in the required fields to create your new weblog. Use the following data for the Name, Description, and Handle fields: The Email Address field will already contain the e-mail address you used when creating your new user. Leave the default values for Locale, Timezone, and Theme, and click on the Create Weblog button to continue. The following page will appear indicating that your weblog was successfully created: Now click on the New Entry link in order to create the following new entry in your weblog: Scroll down the page and click on the Post to Weblog button to post your entry. What just happened? Well, now there's another user in your Roller server, how about that? Your boss is going to be proud of you and very happy, because your company will have a multiuser blog! The next step is to invite other people to create user accounts and weblogs in the Roller blog server. If you're using Roller in your office, just start spreading the word to your colleagues. Or if you're experimenting with Roller in your home, you can invite some friends to blog with you, create a family group blog, and so on. Have a go hero – inviting members to write in your weblog Now that you've learned how other people can register and get a user account in Roller, it would be a good idea to start exploring the Preferences: Members page, where you can invite other Roller users to collaborate in your weblog by posting entries. Roller has three user levels: Administrator: Can create/edit weblog entries and publish them in your weblog. An administrator can also change the Roller theme and templates, and manage weblog users. Author: Can create/edit weblog entries and upload files, but cannot change themes or templates, and cannot manage users. Limited: Can create/edit entries and save them as drafts, but cannot publish them. Go on and create several test user accounts, and try out the three Roller user levels by inviting the test users to collaborate in your weblog. To invite a user, use the Invite new member link under the Actions panel in the Preferences: Members page. Enabling a front page blog Up until now, you've been using your main weblog as the front page for your Roller blog server. Now that you've enabled group blogging, each user can promote his/her weblog(s) individually, or you can create a community front page to show recent posts from all of your user's weblogs. The next exercise will show you how to create and use a front page blog to show posts from all the other weblogs in your Roller blog server. Time for action – enabling a front page blog In this exercise, we're going to create a new weblog to serve as the front page of your entire Roller weblog server. The front page blog will show a list of recent entries from all your other weblogs, and from all the other users' weblogs in your Roller blog server. Log into Roller (in case you're not already logged in) with your administrator account, go to the Main Menu page, and then click on the Create new weblog link under the Actions panel: Type My Roller Community in the Name field, The best Roller blog community in the Description field, and frontpage in the Handle field: Scroll down the page until you locate the Theme field, select the Frontpage theme, and click on the Create Weblog button: The following page will appear, indicating that your frontpage weblog was created successfully: Now click on the Server administration link located in the Actions panel. The Roller Configuration page will show up. Scroll down until you locate the Handle of weblog to serve as frontpage blog field, and replace its contents with frontpage. Then click on the Enable aggregated site-wide frontpage option to enable it: Scroll down the page until you locate the Save button and click on it to save your changes. Now click on the Front Page link in Roller's menu bar:
Read more
  • 0
  • 0
  • 1855

article-image-advanced-blog-management-apache-roller-40-part-2
Packt
03 Feb 2010
4 min read
Save for later

Advanced Blog Management with Apache Roller 4.0: Part 2

Packt
03 Feb 2010
4 min read
Enabling weblog pings Now that you have a Technorati account, let's enable your Roller weblog so that it can ping Technorati automatically each time you post a new entry or edit a previously posted entry. Time for action – enabling automatic pings in your weblog This exercise will show you how to enable automatic pinging in your weblog, so that every time you post a new entry or update some entry you posted before, Technorati will receive a ping and will update your blog status: Go to the Front Page: Weblog Settings tab in your web browser, click on the Preferences tab to see your weblog's configuration page, and click on the Pings link: The Configure Automatic Weblog Pings page will appear next. Scroll down the page until you locate the Technorati row under the Common Ping Targets section: Click on Technorati's Enable link to enable automatic pinging for your weblog, so it can send automatic pings to Technorati: Click on the Send Ping Now button to test whether everything works correctly. Roller will show the following success message: Now you just have to wait until Technorati grabs your blog's most recent information, as shown in the following screenshot: What just happened? Now Technorati will keep your weblog information updated every time you post a new entry in your weblog. Once you register with an aggregator, it's very easy to configure automatic pinging in Roller, as you saw in the previous exercise. Now all you need to do is configure all the pings you can to other aggregators and blog search engines, so that people from everywhere can see your weblog! Have a go hero – configure more ping targets Now that you learned how to configure automatic pings to Technorati for your Roller weblog, check out the other ping targets available in the Common Ping Targets list. Go on and enable all the ping targets that you can in order to promote your weblog in all the available blog search engines and aggregators. You can also register with Digg, StumbleUpon, and the other popular aggregators/blog search engines and add new ping targets for them if you click on the Custom Ping Targets link in the Configure Automatic Weblog Pings page. So what are you waiting for? Go and promote your new Roller weblog! Google webmaster tools Now that you have a cool weblog, it would be great if the weblog would show up in Google every time someone searches for a subject related to the things you're writing, don't you think? That's why Google invented the webmaster tools—a great resource to help you find out how your weblog is interacting with the Google bot. With these tools you can get detailed information about broken links, popular keywords, and basically, all the stuff you need to have a successful weblog! Time for action – enabling Google webmaster tools This exercise will show you how to configure Google webmaster tools for your Roller weblog, so you can start receiving important information about visitors and how your weblog interacts with Google: Open your web browser and type https://www.google.com/webmasters/tools to go to the Google webmaster tools website: If you created a Gmail account when installing Roller, you can use it to sign in to Google webmaster tools. Or you can create a new Gmail account in case you don't have one already. Click on the Sign In button when ready. The Google webmaster tools Home page will appear next. Click on the Add a Site button at the bottom to add your Roller weblog: Now enter your weblog's URL in the pop-up box and click on Continue: Google will show you a Meta tag that you need to copy and paste in your Roller weblog. Select the meta tag, right-click on it, and click on Copy: Now open a new tab in your web browser, log into your Roller weblog, and go to the Design tab. The Weblog Theme page will appear. Click on the Custom Theme option and then on the Update Theme button: Roller will show the Successfully set theme to – custom message. Click on the Templates link and then select the Weblog template: Scroll down the page until you locate the </head> HTML tag and paste the Google webmaster tools meta tag right before it, as shown in the following screenshot: Scroll down the page until you locate the Save button and click on it. Roller will show the Template updated successfully message. Return to the Google webmaster tools tab in your web browser and click on the Verify button to verify your weblog: If all goes well, Google will verify your weblog and take you to the Dashboard:
Read more
  • 0
  • 0
  • 2113

article-image-advanced-blog-management-apache-roller-40-part-3
Packt
03 Feb 2010
4 min read
Save for later

Advanced Blog Management with Apache Roller 4.0: Part 3

Packt
03 Feb 2010
4 min read
Weblog clients There are times when logging into your Roller weblog to post a new entry can be a tedious process, especially when you have two or more weblogs about different subjects. Let's say that you have to write stuff in your company's blog, and you also write in your personal Roller blog. You can open two web browser windows and log into each blog separately, but it would be better to use a weblog client, as I'll show you in the next exercise. Time for action – using Google docs as your weblog client In this exercise, you'll learn to use Google docs as your weblog client to post entries in your Roller weblogs without having to log in: Open your web browser, go to http://docs.google.com, log in with your username and password (if you don't have a Google account, this is your chance to get one!), then click on the New button, and select the Document option: Your browser will open a new tab for the new Google docs document. Type This is my first post to my Roller weblog from Google Docs! in the word processor writing area, as shown in the following screenshot: Now click on the File menu and select the Save option to save your draft in Google docs: Google docs assigns the title for your document automatically, based on its content. To change the title of your post, click on it: Type Posting to Roller from Google Docs in the dialog that will show up next, and click on OK to continue: Google docs will show the new title for your post: Now click on the Share button and select the Publish as web page option: The Publish this document dialog will appear. Click on the change your blog site settings link to enter your Roller weblog information: The Blog Site Settings dialog will appear next. Choose the My own server / custom option and select MetaWeblog API in the API field. In the URL field you need to type the complete path to Roller's web services—http://alromero.noip.org/roller/roller-services/xmlrpc, in my case. You just need to replace the alromero.no-ip.org part with your dynamic hostname. Then type your Roller username, password, and weblog name, and select the Include the document title when posting option, as shown in the following screenshot: Click on the OK button to save your weblog settings, and then click on the Post to blog button in the Publish this document dialog: A confirmation dialog will pop-up, asking if you want to post the document to your blog now. Click on OK to continue: Google docs will show the This document has been published to your blog success message: Click on the Save & Close button at the upper-right part of the screen to save your document and return to the Google docs main page, then click on Sign out to exit Google docs. Now go to your Roller weblog's main page, to see the post you published from Google docs: What just happened? See how easy it is to use a weblog client, so that you don't need to log into your Roller weblog to post a new entry? And if you want to post to a different Roller weblog, you just need to change your username, blog ID, or URL. There are several other weblog clients available that you can use, depending on your operating system, but all weblog clients work in a similar way. Have a go hero – try out other weblog clients Go and try out some other weblog clients, to see which one is best for you. In Windows, you can use Windows Live Writer (http://download.live.com/writer) and w.bloggar (http://bloggar.com/). In Linux, you can try out BloGTK (https://launchpad.net/blogtk/).
Read more
  • 0
  • 0
  • 1871

article-image-rendering-images-typo3-43-part-1
Packt
03 Feb 2010
4 min read
Save for later

Rendering Images in TYPO3 4.3: Part 1

Packt
03 Feb 2010
4 min read
Rendering images using content elements Content elements offer a variety of ways for editors to include images. We will examine these here. Here is a typical selection menu that editor is presented with: A great way to start is to assemble pages from the Regular text element and the Text with image elements Getting Ready Make sure Content (default) is selected in Include static, and the CSS Styled Content template is included in the Include static (from extensions) field of the template record of the current page or any page above it in the hierarchy (page tree). To verify, go to the Template module, select the appropriate page, and click edit the whole template record. How to do it... Create the Text with image element. Under the Text tab, enter the text you want to appear on the page. You can use the RTE (Rich Text Editor) to apply formatting, or disable it. We will cover RTE in more detail later in this article. Under the Media tab, select your image settings. If you want to upload the image, use the first field. If you want to use an existing image, use the second field. Under Position, you are able to select where the image will appear in relation to the text. How it works... When the page is rendered in the frontend, the images will be placed next to the text you entered, in the position that you specify. The specific look will depend on the template that you are using. There's more An alternative to the Text with images is an Images only content element. This element gives you similar options, except limits the options to just a display of images. The rest of the options are the same. You can also resize the image, add caption, alt tags for accessibility and search engine optimization, and change default processing options. See the official TYPO3 documentation for details of how these fields work, (http://typo3.org/documentation/document-library/). See also Render video and audio using content elements and rgmediaimages extension Embedding images in RTE Rich Text Editor is great for text entry. By default, TYPO3 ships with htmlArea RTE as a system extension. Other editors are available, and can be installed if needed. Images can be embedded and manipulated within the RTE. This provides one place for content editors to use in order to arrange content how they want it to appear at the frontend of the site. In this recipe, we will see how this can be accomplished. The instructions apply to all forms that have RTE-enabled fields, but we will use the text content element for a simple demonstration. In the Extension Manager, click on htmlArea RTE extension to bring up its options. Make sure that the Enable images in the RTE [enableImages] setting is enabled. If you have a recent version of DAM installed (at least 1.1.0), make sure that the Enable the DAM media browser [enableDAMBrowser] setting is unchecked. This setting is deprecated, and is there for installations using older versions of DAM. How to do it... Create a new Regular text element content element. In the RTE, click on the icon to insert an image as shown in the following screenshot: Choose a file, and click on the icon to insert it into the Text area. You should see the image as it will appear at the frontend of the site. Save and preview. The output should appear similar to the following screenshot: How it works... When you insert an image through the RTE, the image is copied to uploads folder, and included from there. The new file will be resampled and sized down, so, it usually occupies less space and is downloaded faster than the original file. TYPO3 will automatically determine if the original file has changed, and update the file used in the RTE—but you should still be aware of this behaviour. Furthermore, if you have DAM installed, and you have included an image from DAM, you can see the updated record usage. If you view the record information, you should see the Content Element where the image is used:
Read more
  • 0
  • 0
  • 2250
article-image-magentos-architecture-part-2
Packt
01 Feb 2010
7 min read
Save for later

Magento's Architecture: Part 2

Packt
01 Feb 2010
7 min read
Modules and how they work within the system Magento primarily works on a base of modules. All functionality is divided up into modules that make up the system overall. It's important to understand what each module does and how to go about adding modules to the system, in order to understand the architecture of modules themselves. Distribution of the modules between directories All modules are located within the /app/code/ directory. Directories are commonly referred to as codePools. There are three possible locations for all modules that relate to the system. They are all split by type to prevent any confusion: community—For community-distributed extensions, usually those that we have installed through Magento Connect or have downloaded from a source, other than our own. Anything installed through Magento Connect will be installed here automatically. core—Reserved for core Magento modules, so that we cannot directly overwrite or interfere with them. We keep our modules out of core to avoid any conflict with the core modules or any future updates. Anything from a Magento upgrade or any new Magento modules will go into this directory. Local—This is where we should be placing our modules when they are either under local development or are not distributed among the community. It's best to keep anything that we develop in this directory, so as to not interfere with the core or community modules. Nothing will be automatically installed here, unless we have physically uploaded it. Modules included with Magento Included modules in the core folder of default Magento installation are as follows: Mage_Admin Mage_AdminNotification Mage_Api Mage_Backup Mage_Bundle Mage_Catalog Mage_CatalogIndex Mage_CatalogInventory Mage_CatalogRule Mage_CatalogSearch Mage_Checkout Mage_Cms Mage_Contacts Mage_Core Mage_Cron Mage_Customer Mage_Dataflow Mage_Directory Mage_Downloadable Mage_Eav Mage_GiftMessage Mage_GoogleAnalytics Mage_GoogleBase Mage_GoogleCheckout Mage_GoogleOptimizer Mage_Install Mage_Log Mage_Media Mage_Newsletter Mage_Page Mage_Paygate Mage_Payment Mage_Paypal Mage_PaypalUk Mage_Poll Mage_ProductAlert Mage_Rating Mage_Reports Mage_Review Mage_Rss Mage_Rule Mage_Sales Mage_SalesRule Mage_Sendfriend Mage_Shipping Mage_Sitemap Mage_Tag Mage_Tax Mage_Usa Mage_Weee Mage_Wishlist Setting up the folder structure of a module Let's presume that we want to set up a module's folder structure, ready for development. Our module's core folders will be placed in /app/code/local/Book/Example/. These folders will primarily be used for storing our code that makes the module work. The folder structure breaks down as follows: Block/ controllers/ etc/ Model/ Mysql4/ Book/ sql/ book_setup/ Typically, developers will pick or choose each folder, depending on whether or not they're going to use it within their module. Note that Model/Mysql4/Book/ has its first letter in uppercase, whereas sql/book_setup/ does not. We must be sure to keep this the same way throughout our development. Template files for the frontend of our module will be stored as follows: XML files will be stored in /app/design/frontend/<interface>/<theme>/layout/example/ Output files will be stored in /app/design/frontend/<interface>/<theme>/template/example/ Any admin template files for the frontend of our module will be stored as follows: XML files will be stored in /app/design/adminhtml/<interface>/<theme>/layout/example/ Output files will be stored in /app/design/adminhtml/<interface>/<theme>/template/example/ Here's a breakdown of what each folder is for: Block/—For processing of all display blocks called by the system for the module. These are controllers that will be called in the XML layout files within a theme, in order to display something. controllers/—Our controllers that support the application and structurally keep things together. etc/—Configuration files for the module, for declaring things such as the default options when installed and declaring all blocks, models, and install/upgrade actions. Model/—For placement of all models to support controllers in the module. sql/—SQL actions when the module is installed/upgraded/uninstalled. Zend Framework and its role within Magento Magento (at its raw PHP base) is built on the Zend Framework. From the database class to the handling of URLs, Magento is in its raw form, with Zend Framework doing all the work. Alongside this, Varien has built several core modules on top of the Zend Framework, in order to tie it altogether into the system as we know it. What is Zend Framework Zend Framework's official site best describes the framework as follows: Zend Framework (ZF) is an open source framework for developing web applications and services with PHP 5. ZF is implemented using 100% object-oriented code. The component structure of ZF is somewhat unique; each component is designed with few dependencies on other components. This loosely coupled architecture allows developers to use components individually. We often call this a "use-at-will" design. While they can be used separately, Zend Framework components in the standard library form a powerful and extensible web application framework when combined. ZF offers a robust, high performance MVC implementation, a database abstraction that is simple to use, and a forms component that implements HTML form rendering, validation, and filtering so that developers can consolidate all of these operations using one easy-to-use, object-oriented interface. Other components, such as Zend_Auth and Zend_Acl, provide user authentication and authorization against all common credential stores. Still others implement client libraries to simply access to the most popular web services available. Whatever your application needs are, you're likely to find a Zend Framework component that can be used to dramatically reduce development time with a thoroughly tested foundation. How Zend Framework works The Zend Framework (at its core) is designed to be used as a package or separate modules. This (among other features) makes it unique, as most other frameworks are designed to be used plainly as frameworks or not at all. However, the Zend Framework comes with classes that allow us to use it as a standalone framework and develop with it as one. Instead of being delivered with a preset amount of directories and layout for developers, it only suggests a layout for our files. This means that we can adapt the framework to meet our current workflow and choose how much we adapt the workflow to fit the framework. It's role and effect in Magento The Zend Framework allows Magento to focus on the core issues at hand. It removes a lot of the work on the database and core structural classes and puts the work towards fixing and adding to core modules of Magento. Most importantly it gives developers a standard approach to development that they can move across and apply to Magento. The standard development practices help greatly in adopting Magento as a platform and make it easier for developers having experience with Zend Framework to adapt to Magento. More information on learning the Zend Framework and resources can be found at the back of this book in the Appendix attached. Its official site is located at: http://framework.zend.com/. Backing up Magento's data It's important to know how to back up our site, to ensure that our installation's data is not lost (if ever things go bad). It is recommended to back up our Magento installation: Regularly as a base to ensure that there are incremental backups of our system Before installing new modules or themes from Magento Connect When developing modules Before upgrading our system
Read more
  • 0
  • 0
  • 1998

article-image-magentos-architecture-part-1
Packt
01 Feb 2010
5 min read
Save for later

Magento's Architecture: Part 1

Packt
01 Feb 2010
5 min read
Magento's base structure The fundamental knowledge of Magento's architecture begins with its file structure. It's important to know what goes where by default, so that we may position our new files accordingly, especially in terms of ensuring that our development doesn't overwrite core files. Base directory The default installation contains the following files and directories in the base directory: .htaccess .htaccess.sample 404 (directory) app (directory) cron.php downloader (directory) favicon.ico index.php index.php.sample js (directory) lib (directory) LICENSE_AFL.txt LICENSE.txt media (directory) pear pkginfo (directory) report (directory) skin (directory) var (directory) Each of these files and directories has a different purpose. We'll go through them to ensure that we understand the function of each. This will help us later, if ever we need to find something specific, or when developing. It will also be helpful when we'll be looking to place the files coming out of our new module into the appropriate directory. The function of each of the files in the base directory The following is a run through of all the files in the base directory, to show us what they do: .htaccess—This file controls mod_rewrite for fancy URLs and sets configuration server variables (such as memory limit) and PHP maximum execution time, so that Magento can run better. .htaccess.sample—Works as a backup for .htaccess, so that we know the default .htaccess file (if ever we edit it and need to backtrack). cron.php—The file that should be executed as a cron job every few minutes to ensure that Magento's wide caching doesn't affect our server's performance. favicon.ico—Magento's default favicon; it's the small icon that appears in the toolbar of our browser. index.php—The main loader file for Magento and the file that initializes everything. index.php.sample—The base template for new index.php files, useful when we have edited the index.php file and need to backtrack. LICENSE_AFL.txt—It contains the Academic Free License that Magento is distributed under. LICENSE.txt—It contains the Open Software License that Magento is distributed under. pear—This controls all automatic updating via the downloader and SSH. This file is initialized and handles the updating of each individual module that makes up Magento. php.ini—A sample php.ini file for raw PHP server variables recommended when setting up Magento on our server. This should not be used as a complete replacement, but only as a guide to replace certain lines of the php.ini server file. It is useful when overriding these variables when .htaccess isn't enabled on our server. The function of each of the folders in the base directory The following is a run through of all the folders in the base directory to show us their contents: 404—The default 404 template and skin storage folder for Magento. app—All code (modules), design (themes), configuration, and translation files are stored in this directory. This is the folder that we'll be working in extensively, when developing a Magento powered website. Also contained in this folder are the template files for the default administration theme and installation. downloader—The web downloader for upgrading and installing Magento without the use of SSH. js—The core folder where all JavaScript code included with the installation of Magento is kept. We will find all pre-compiled libraries of JavaScript here. lib—All PHP libraries used to put together Magento. This is the core code of Magento that ties everything together. The Zend Framework is also stored within this directory. media—All media is stored here. Primarily for images out of the box, this is where all generated thumbnails and uploaded product images will be stored. It is also the container for importing images, when using the mass import/export tools. pkginfo—Short form of package information, this directory contains text files that largely operate as debug files to inform us about changes when modules are upgraded in any way. report—The skin folder for the reports that Magento outputs when any error occurs. skin—All assets for themes are stored within this directory. We typically find images, JavaScript files, CSS files, and Flash files relating to themes, in this directory. However, it can be used to store any assets associated with a theme. It also contains the skin files for the installation of skins and administration templates. var—Typically where we will find all cache and generated files for Magento. We can find the cache, sessions (if storing as files), data exports, database backups, and cached error reports in this folder. The template system architecture The template architecture is broken into three areas—two for development of the theme and one for the containment of the assets: /app/design/frontend/default/<template_name>/ layout/—For all the XML files declaring which module tied functions should be called to which template files template/—For all the templates processing the output that is passed from functions called from layout/ and structured into the final output to the user. /skin/frontend/default/<template_name>/—For the containment of all assets relating to our template, images, CSS, Flash, and JavaScript. Structural blocks and content blocks Each theme contains structural and content blocks. Structural blocks are the ones that lay out the theme into sections. Let's take a look at a three-column layout. The following are the structural blocks in a three-column layout: header left content right footer Here's a visual representation of those structural blocks laid over the Magento demo store: In each of the structural blocks, we then have content blocks that give each structural block its content for output to the browser. Let's take the right column; our content blocks set for this column on a standard theme could be: mini cart recently viewed products newsletter subscription block poll
Read more
  • 0
  • 0
  • 6646

article-image-typo3-connecting-external-apis-flicker-and-youtube
Packt
01 Feb 2010
10 min read
Save for later

TYPO3 for Connecting External APIs: Flicker and Youtube

Packt
01 Feb 2010
10 min read
Getting recent Flickr photos The Flickr API is very powerful and gives access to just about everything a user can do manually. You can write scripts to automatically download latest pictures from a photostream, download photos or videos tagged with a certain keyword, or post comments on photos. In this recipe, we will make use of the phpFlickr library to perform some basic listing functions for photos in Flickr. Getting ready Before you start, you should sign up for a free Flickr account, or use an existing one. Once you have the account, you need to sign up for an API key. You can go to Your Account, and select the Extending Flickr tab. After filling in a short form, you should be given two keys—API key and secret key. We will use these in all Flickr operations. We will not go through the steps required for integration into extensions, and will leave this exercise to the reader. The code we present can be used in both frontend plugins and backend modules. As was previously mentioned, we will be using the phpFlickr library. Go to http://phpflickr.com/ to download the latest version of the library and read the complete documentation. How to do it... Include phpFlickr, and instantiate the object (modify the path to the library, and replace api-key with your key): require_once("phpFlickr.php");$flickrService = new phpFlickr('api-key'); Get a list of photos for a specific user: $photos = $flickrService->people_getPublicPhotos('7542705@N08'); If the operation succeeds, $photos will contain an array of 100 (by default) photos from the user. You could loop over the array, and print a thumbnail with a link to the full image by: foreach ($photos['photos']['photo'] as $photo) { $imgURL = $flickrService->buildPhotoURL($photo, 'thumbnail'); print '<a href="http://www.flickr.com/photos/' . $photo['owner'] . '/' . $photo['id'] . '">' . '<img src="' . $imgURL . '" /></a><br />';} How it works... The Flickr API is exposed as a set of REST services, which we can issue calls to. The tough work of signing the requests and parsing the results is encapsulated by phpFlickr, so we don't have to worry about it. Our job is to gather the parameters, issue the request, and process the response. In the example above, we got a list of public photos from a user 7542705@N08. You may not know the user ID of the person you want to get photos for, but Flickr API offers several methods for finding the ID: $userID = $flickrService->people_findByEmail($email);$userID = $flickrService->people_findByUsername($username); If you have the user ID, but want to get more information about the user, you can do it with the following calls: // Get more info about the user:$flickrService->people_getInfo($userID);// Find which public groups the user belongs to:$flickrService->people_getPublicGroups($userID);// Get user's public photos:$flickrService->people_getPublicPhotos($userID); We utilize the people_getPublicPhotos method to get the user's photostream. The returned array has the following structure: Array( [photos] => Array ( [page] => 1 [pages] => 8 [perpage] => 100 [total] => 770 [photo] => Array ( [0] => Array ( [id] => 3960430648 [owner] => 7542705@N08 [secret] => 9c4087aae3 [server] => 3423 [farm] => 4 [title] => One Cold Morning [ispublic] => 1 [isfriend] => 0 [isfamily] => 0 ) […] ) )) We loop over the $photos['photos']['photo'] array, and for each image, we build a URL for the thumbnail using the buildPhotoURL method, and a link to the image page on Flickr. There's more... There are lots of other things we can do, but we will only cover a few basic operations. Error reporting and debugging Occasionally, you might encounter an output you do not expect. It's possible that the Flickr API returned an error, but by default, it's not shown to the user. You need to call the following functions to get more information about the error: $errorCode = $flickrService->getErrorCode();$errorMessage = $flickrService->getErrorMsg(); Downloading a list of recent photos You can get a list of the most recent photos uploaded to Flickr using the following call: $recentPhotos = $flickrService->photos_getRecent(); See also Uploading files to Flickr Uploading DAM files to Flickr Uploading files to Flickr In this recipe, we will take a look at how to upload files to Flickr, as well as how to access other authenticated operations. Although many operations don't require authentication, any interactive functions do. Once you have successfully authenticated with Flickr, you can upload files, leave comments, and make other changes to the data stored in Flickr that you wouldn't be allowed to do without authentication. Getting ready If you followed the previous example, you should have everything ready to go. We'll assume you have the $flickrService object instantiated ready. How to do it... Before calling any operations that require elevated permissions, the service needs to be authenticated. Add the following code to perform the authentication: $frob = t3lib_div::_GET('frob');if (empty($frob)) { $flickrService->auth('write', false);} else { $flickrService->auth_getToken($frob);} Call the function to upload the file: $flickrService->sync_upload($filePath); Once the file is uploaded, it will appear in the user's photostream. How it works... Flickr applications can access any user's data if the user authorizes them. For security reasons, users are redirected to Yahoo! to log into their account, and confirm access for your application. Once your application is authorized by a user, a token is stored in Flickr, and can be retrieved at any other time. $flickrService->auth() requests permissions for the application. If the application is not yet authorized by the user, he/she will be redirected to Flickr. After giving the requested permissions, Flickr will redirect the user to the URL defined in the API key settings. The redirected URL will contain a parameter frob. If present, $flickrService->auth_getToken($frob); is executed to get the token and store it in session. Future calls within the session lifetime will not require further calls to Flickr. If the session is expired, the token will be requested from Flickr service, transparent to the end user. There's more... Successful authentication allows you to access other operations that you would not be able to access using regular authentication. Gaining permissions There are different levels of permissions that the service can request. You should not request more permissions than your application will use. API call Permission level $flickrService->auth('read', false); Permissions to read users' files, sets, collections, groups, and more. $flickrService->auth('write', false); Permissions to write (upload, create new, and so on). $flickrService->auth('delete', false); Permissions to delete files, groups, associations, and so on. Choosing between synchronous and asynchronous upload There are two functions that perform a file upload: $flickrService->sync_upload($filePath);$flickrService->async_upload($filePath); The first function continues execution only after the file has been accepted and processed by Flickr. The second function returns after the file has been submitted, but not necessarily processed. Why would you use the asynchronous method? Flickr service may have a large queue of uploaded files waiting to be processed, and your application might timeout while it's waiting. If you don't need to access the uploaded file right after it was uploaded, you should use the asynchronous method. See also Getting recent Flickr photos Uploading DAM files to Flickr Uploading DAM files to Flickr In this recipe, we will make use of our knowledge of the Flickr API and the phpFlickr interface to build a Flickr upload service into DAM. We will create a new action class, which will add our functionality into a DAM file list and context menus. Getting ready For simplicity, we will skip the process of creating the extension. You can download the extension dam_flickr_upload and view the source code. We will examine it in more detail in the How it works... section. How to do it... Sign up for Flickr, and request an API key if you haven't already done so. After you receive your key, click Edit key details. Fill in the application title and description as you see fit. Under the call back URL, enter the web path to the dam_flickr_upload/mod1/index.php file. For example, if your domain is http://domain.com/, TYPO3 is installed in the root of the domain, and you installed dam_flickr_upload in the default local location under typo3conf, then enter http://domain.com/typo3conf/ext/dam_flickr_upload/mod1/index.php You're likely to experience trouble with the callback URL if you're doing it on a local installation with no public URI. Install dam_flickr_upload. In the Extension Manager, under the extension settings, enter the Flickr API key and the secret key you have received. Go to the Media | File module, and click on the control button next to a file. Alternatively, select Send to Flickr in the context menu, which appears if you click on the file icon, as seen in the following screenshot: A new window will open, and redirect you to Flickr, asking you to authorize the application for accessing your account. Confirm the authorization by clicking the OK, I'LL AUTHORIZE IT button. The file will be uploaded, and placed into your photostream on Flickr. Subsequent uploads will no longer need explicit authorization. A window will come up, and disappear after the file has been successfully uploaded. How it works... Let's examine in detail how the extension works. First, examine the file tree. The root contains the now familiar ext_tables.php and ext_conf_template.txt files.The Res directory contains icons used in the DAM. The Lib directory contains the phpFlickr library. The Mod1 directory contains the module for uploading. ext_conf_template.txt This file contains the global extension configuration variables. The two variables defined in this file are the Flickr API key and the Flickr secret key. Both of these are required to upload files. ext_tables.php As was mentioned previously, ext_tables.php is a configuration file that is loaded when the TYPO3 framework is initializing. tx_dam::register_action ('tx_dam_action_flickrUpload', 'EXT:dam_flickr_upload/class.tx_dam_flickr_upload_action.php:&tx_dam_flickr_upload_action_flickrUpload'); This line registers a new action in DAM. Actions are provided by classes extending the tx_dam_actionbase class, and define operations that can be performed on files and directories. Examples of actions include view, cut, copy, rename, delete, and more. The second parameter of the function defines where the action class is located. $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dam_flickr_upload']['allowedExtensions'] = array('avi', 'wmv', 'mov', 'mpg', 'mpeg','3gp', 'jpg', 'jpeg', 'tiff', 'gif', 'png'); We define an array of file types that can be uploaded to Flickr. This is not hardcoded in the extension, but stored in ext_tables.php, so that it can be overwritten by extensions wanting to limit or expand the functionality to other file types.
Read more
  • 0
  • 0
  • 2760
article-image-basic-doctest-python
Packt
29 Jan 2010
9 min read
Save for later

Basic Doctest in Python

Packt
29 Jan 2010
9 min read
Doctest will be the mainstay of your testing toolkit. You'll be using it for tests, of course, but also for things that you may not think of as tests right now. For example, program specifications and API documentation both benefit from being written as doctests and checked alongside your other tests. Like program source code, doctest tests are written in plain text. Doctest extracts the tests and ignores the rest of the text, which means that the tests can be embedded in human-readable explanations or discussions. This is the feature that makes doctest so suitable for non-classical uses such as program specifications. Time for action – creating and running your first doctest We'll create a simple doctest, to demonstrate the fundamentals of using doctest. Open a new text file in your editor, and name it test.txt. Insert the following text into the file: This is a simple doctest that checks some of Python's arithmeticoperations.>>> 2 + 24>>> 3 * 310 We can now run the doctest. The details of how we do that depend on which version of Python we're using. At the command prompt, change to the directory where you saved test.txt. If you are using Python 2.6 or higher, type: $ python -m doctest test.txt If you are using python 2.5 or lower, the above command may seem to work, but it won't produce the expected result. This is because Python 2.6 is the first version in which doctest looks for test file names on the command line when you invoke it this way. If you're using an older version of Python, you can run your doctest by typing: $ python -c "__import__('doctest').testfile('test.txt')" When the test is run, you should see output as shown in the following screen: What just happened? You wrote a doctest file that describes a couple of arithmetic operations, and executed it to check whether Python behaved as the tests said it should. You ran the tests by telling Python to execute doctest on the files that contained the tests. In this case, Python's behavior differed from the tests because according to the tests, three times three equals ten! However, Python disagrees on that. As doctest expected one thing and Python did something different, doctest presented you with a nice little error report showing where to find the failed test, and how the actual result differed from the expected result. At the bottom of the report, is a summary showing how many tests failed in each file tested, which is helpful when you have more than one file containing tests. Remember, doctest files are for computer and human consumption. Try to write the test code in a way that human readers can easily understand, and add in plenty of plain language commentary. The syntax of doctests You might have guessed from looking at the previous example: doctest recognizes tests by looking for sections of text that look like they've been copied and pasted from a Python interactive session. Anything that can be expressed in Python is valid within a doctest. Lines that start with a >>> prompt are sent to a Python interpreter. Lines that start with a ... prompt are sent as continuations of the code from the previous line, allowing you to embed complex block statements into your doctests. Finally, any lines that don't start with >>> or ..., up to the next blank line or >>> prompt, represent the output expected from the statement. The output appears as it would in an interactive Python session, including both the return value and the one printed to the console. If you don't have any output lines, doctest assumes it to mean that the statement is expected to have no visible result on the console. Doctest ignores anything in the file that isn't part of a test, which means that you can place explanatory text, HTML, line-art diagrams, or whatever else strikes your fancy in between your tests. We took advantage of that in the previous doctest, to add an explanatory sentence before the test itself. Time for action – writing a more complex test We'll write another test (you can add it to test.txt if you like) which shows off most of the details of doctest syntax. Insert the following text into your doctest file (test.txt), separated from the existing tests by at least one blank line: Now we're going to take some more of doctest's syntax for a spin.>>> import sys>>> def test_write():... sys.stdout.write("Hellon")... return True>>> test_write()HelloTrue Think about it for a moment: What does this do? Do you expect the test to pass, or to fail? Run doctest on the test file, just as we discussed before. Because we added the new tests to the same file containing the tests from before, we still see the notification that three times three does not equal ten. Now, though, we also see that five tests were run, which means our new tests ran and succeeded. What just happened? As far as doctest is concerned, we added three tests to the file. The first one says that when we import sys, nothing visible should happen. The second test says that when we define the test_write function, nothing visible should happen. The third test says that when we call the test_write function, Hello and True should appear on the console, in that order, on separate lines. Since all three of these tests pass, doctest doesn't bother to say much about them. All it did was increase the number of tests reported at the bottom from two to five. Expecting exceptions That's all well and good for testing that things work as expected, but it is just as important to make sure that things fail when they're supposed to fail. Put another way; sometimes your code is supposed to raise an exception, and you need to be able to write tests that check that behavior as well. Fortunately, doctest follows nearly the same principle in dealing with exceptions, that it does with everything else; it looks for text that looks like a Python interactive session. That means it looks for text that looks like a Python exception report and traceback, matching it against any exception that gets raised. Doctest does handle exceptions a little differently from other tools. It doesn't just match the text precisely and report a failure if it doesn't match. Exception tracebacks tend to contain many details that are not relevant to the test, but which can change unexpectedly. Doctest deals with this by ignoring the traceback entirely: it's only concerned with the first line—Traceback (most recent call last)—which tells it that you expect an exception, and the part after the traceback, which tells it which exception you expect. Doctest only reports a failure if one of these parts does not match. That's helpful for a second reason as well: manually figuring out what the traceback would look like, when you're writing your tests would require a significant amount of effort, and would gain you nothing. It's better to simply omit them. Time for action – expecting an exception This is yet another test that you can add to test.txt, this time testing some code that ought to raise an exception. Insert the following text into your doctest file (Please note that the last line of this text has been wrapped due to the constraints of the article's format, and should be a single line): Here we use doctest's exception syntax to check that Python iscorrectly enforcing its grammar.>>> def faulty():... yield 5... return 7Traceback (most recent call last):SyntaxError: 'return' with argument inside generator(<doctest test.txt[5]>, line 3) The test is supposed to raise an exception, so it will fail if it doesn't raise the exception, or if it raises the wrong exception. Make sure you have your mind wrapped around that: if the test code executes successfully, the test fails, because it expected an exception. Run the tests using doctest and the following screen will be displayed: What just happened? Since Python doesn't allow a function to contain both yield statements and return statements with values, having the test to define such a function caused an exception. In this case, the exception was a SyntaxError with the expected value. As a result, doctest considered it a match with the expected output, and thus the test passed. When dealing with exceptions, it is often desirable to be able to use a wildcard matching mechanism. Doctest provides this facility through its ellipsis directive, which we'll discuss later Expecting blank lines in the output Doctest uses the first blank line to identify the end of the expected output. So what do you do, when the expected output actually contains a blank line? Doctest handles this situation by matching a line that contains only the text <BLANKLINE> in the expected output, with a real blank line in the actual output. Using directives to control doctest Sometimes, the default behavior of doctest makes writing a particular test inconvenient. That's where doctest directives come to our rescue. Directives are specially formatted comments that you place after the source code of a test, which tell doctest to alter its default behavior in some way. A directive comment begins with # doctest:, after which comes a comma-separated list of options, that either enable or disable various behaviors. To enable a behavior, write a + (plus symbol) followed by the behavior name. To disable a behavior, white a – (minus symbol) followed by the behavior name. Ignoring part of the result It's fairly common that only part of the output of a test is actually relevant to determining whether the test passes. By using the +ELLIPSIS directive, you can make doctest treat the text ... (called an ellipsis) in the expected output as a wildcard, which will match any text in the output. When you use an ellipsis, doctest will scan ahead until it finds text matching whatever comes after the ellipsis in the expected output, and continue matching from there. This can lead to surprising results such as an ellipsis matching against a 0-length section of the actual output, or against multiple lines. For this reason, it needs to be used thoughtfully.
Read more
  • 0
  • 0
  • 7899

article-image-migrating-mysql-table-using-oracle-sql-developer-15
Packt
29 Jan 2010
4 min read
Save for later

Migrating a MySQL table using Oracle SQL Developer 1.5

Packt
29 Jan 2010
4 min read
Oracle SQL Developer Tool is a stand alone graphic database developer tool that connects to Oracle as well as third-party databases which can be used to perform a variety of tasks from running simple queries to migration of databases from third party vendor products to Oracle. This article by Dr. Jayaram Krishnaswamy, shows how the reader may use Oracle's most recent tool, the Oracle SQL Developer 1.5 to work with the MySQL database. An example of migrating a table in MySQL to Oracle 10G XE is also described. The Oracle SQL Developer Tool has steadily improved from its beginnings in version 1.1. The earlier versions are briefly explained here. The latest version, SQL Developer 1.5.4 released in March 2009 was described in this article. The SQL Developer tool[(1.5.4.59.40)] bundle can be downloaded from Oracle's web site, Oracle Technology Products. When you unzip the bundle you are ready to start using this tool. You may get an even more recent version of this tool as it is continuously updated. It is assumed that you have a MySQL Server that you can connect to and that you have the required credentials. The MySQL server used in developing this article was installed when the XAMPP bundle was installed. Reader will benefit by reading earlier MySQL articles 1, 2, 3 on the Packt site. Connecting to MySQL Out of the box Oracle SQL Developer 1.5.4 only supports Oracle and MS Access. The product documents clearly says that it can connect to other database products. This article will show how this is achieved. In order to install products from Oracle you must have username and password for the Oracle web Account. Bring up the Oracle SQL Developer application by clicking the executable. The program starts up and after a while the user interface gets displayed as shown. Right click on Connection, the New Connection page opens as shown displaying the default connection to the resident Oracle 10G XE server. Click the menu item Help and choose "Check for Updates". This brings up the wizard displaying the Welcome screen as shown in the next figure. Click Next. The "Source" page of the wizard shows up as shown. The updates for Oracle SQL Developer is already chosen. Place a check mark for "Third Party SQL Developer Extensions". You can choose to install looking for updates on the internet or from the downloaded bundle, if it exists. First try the internet and click Next. This brings up the "Updates" page of the wizard as shown in the next figure. Read the warning on this window. The extensions are not evaluated by Oracle but available. The details of available extensions are as follows: OrindaBuild Java Code Generator version 6.1.20090331 shown in the next figure. The JTDS DBC Driver version 11.1.58.17 shown in the next figure. The MYSQL JDBC driver shown in the next figure: The last one is a patch for the Oracle SQL Developer to fix some of the import, LDAP and performance issues as shown. For this article only the JTDS JDBC driver for MS SQL Server and the MySQL JDBC options were checked. The License agreements are for the JTDS drivers. Click Next. The License agreements must be accepted. Click I Agree. Click Next. This is the download step of the wizard. To proceed further you must have the Oracle Web Account username and password. Here you have the option to signup as well. After a while the new extensions are downloaded as shown in the next figure. Click Finish to close the wizard. You need to restart SQL Developer to complete the installation of the extensions. Click Yes on the "Confirm Exit" window that shows up. Now, when you click New Connection to create a new connection you display the "New / Select Database Connection" as shown. You can now see that other 3rd party databases are added to the window. Choose the tab for MySQL. Fill in the required details as shown in the next figure appropriate for your MySQL installation. You must provide a name for the connection. Herein the connection is named, My_MySQL. The credentials must be provided as shown or that which is appropriate for your installation. The port is the default designated for this server when you install the product. You may accept the other defaults on this page and click Test. The word "success" gets displayed in the status label at bottom left. The connection name and connection details gets added to the page shown above.
Read more
  • 0
  • 0
  • 8687
Modal Close icon
Modal Close icon