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-dynamic-theming-drupal-6-part-2
Packt
24 Oct 2009
8 min read
Save for later

Dynamic Theming in Drupal 6 - Part 2

Packt
24 Oct 2009
8 min read
Creating Dynamic CSS Styling In addition to creating dynamic templates, the Drupal system also enables you to apply CSS dynamically. Drupal creates unique identifiers for various elements of the system and you can use those identifiers to create specific CSS selectors. As a result, you can provide styling that responds to the presence (or absence) of specific conditions on any given page. Two of the most common uses of this technique are covered below: The creation of node-specific styles and the use of $body_classes. Using Dynamic Selectors for Nodes The system generates a unique ID for each node on the website. We can use that unique ID to activate a unique selector by applying this nomenclature for the selector: #node-[nid] {} For example, assume you wish to add a border to the node with the ID of 2. Simply create a new div in style.css with the name: #node-2 {border: 1px solid #336600} Changing the Body Class Based on body_classes One of the most useful dynamic styling tools introduced in Drupal 6 is the implementation of $body_classes. This variable is intended specifically as an aid to dynamic CSS styling. It allows for the easy creation of CSS selectors that are responsive to the layout of the page. This technique is typically used to control the styling where there may be one, two or three columns displayed, depending on the page and the content. Prior to Drupal 6, $layout was used to detect the page layout, that is, one, two or three columns. While $layout can technically still be used, the better practice is to use $body_classes. Implementing $body_classes is a simple matter; just add $body_classes to the body tag of your page.tpl.php file—the Drupal system will do the rest. Once the body tag is altered to include this variable, the class associated with the body tag will change automatically in response to the conditions on the page at that time. Now, all you have to do is create the CSS selectors that you wish to see applied in the various situations. Let's step through this with a quick example. Open up your page.tpl.php file and modify the body tag as follows: <body class="<?php print $body_classes; ?>"> This will now automatically create a class for the page based on the conditions on the page. The chart below shows the options this presents: Condition Class Available no sidebars .no-sidebar one sidebar .one-sidebar left sidebar visible .sidebar-left right sidebar visible .sidebar-right two sidebars .two-sidebars front page .front not front page .not-front logged in .logged-in not logged in .not-logged-in page visible .page-[page type               node visible .node-type-[name of type]       $body_classes provides the key to easily creating a theme that includes collapsible sidebars. To set up this functionality, modify the page.tpl.php file to include $body_classes. Now, go to the style.css file and create the following selectors: .one-sidebar {}.sidebar-left {}.sidebar-right {}.no-sidebar {}.two-sidebars {} The final step is to create the styling for each of the selectors above (as you see fit). When the site is viewed, the system-generated value of $body_classes will determine which selector is applied. You can now specify, through the selectors above, exactly how the page appears—whether the columns collapse, the resulting widths of the remaining columns, and so on , and so on. Working with Template Variables As we have seen, above, Drupal produces variables that can be used to enhance the functionality of themes. Typically, a theme-related function returns values reflecting the state of the page on the screen. A function may indicate, for example, whether the page is the front page of the site, or whether there are one, two, or three active columns (for example, the variable $body_classes). Tapping into this information is a convenient way for a theme developer to style a site dynamically. The default Drupal variables cover the most common (and essential) functions, including creating unique identifiers for items. Some of the Drupal variables are unique to particular templates; others are common to all. In addition to the default variables, you can also define your own variables. Using the function theme_preprocess(), you can either set new variables, or unset existing ones that you do not want to use. In Drupal 6, preprocess functions have made working with variables easier and cleaner. By using the preprocessor, you can set up variables within your theme that can be accessed by any of your templates. The code for the preprocess function is added to your template.php file, thereby keeping the actual template files (the .tpl.php files) free of unnecessary clutter. Note that the preprocess functions only apply to theming hooks implemented as templates; plain theme functions do not interact with the preprocessors. In Drupal 5 and below, the function _phptemplate_variables served the same purpose as the preprocess function. For a list of the expected preprocess functions and their order of precedence, see http://drupal.org/node/223430 Typically, if you wish to implement a preprocessor applicable to your theme, you will use one of the following:   Name of preprocessor Application [engineName]_preprocess This namespace should be used for your base theme. Should be named after the theme engine used by the theme. Will apply to all hooks. [engineName]_preprocess_ [hookname] Should be used for your base theme. Also named after the theme engine applicable to the theme but note that it is specific to a single hook. [themeName]_preprocess This namespace should be used for subthemes. Will apply to all hooks. [themeName]_preprocess_ [hookname] Should be used for subthemes. Note that it is specific to a single hook. Let's look first at intercepting and overriding the default variables and then at creating your own variables. Intercepting and Overriding Variables You can intercept and override the system's existing variables. Intercepting a variable is no different in practice from intercepting a themable function: you simply restate it in the template.php file and make your modifications there, leaving the original code in the core intact. To intercept an existing variable and override it with your new variable, you need to use the function _phptemplate_preprocess(). Add this to your template.php file according to the following syntax: <?phpfunction phptemplate_preprocess(&$vars) {$vars['name'] = add your code here...;}?> Note that nothing should be returned from these functions. The variables have to be passed by reference, as indicated by the ampersand before variables, e.g., &$vars. Let's take a very basic example and apply this. Let's override $title inpage.tpl.php. To accomplish this task, add the following code to the template.php file: <?php function phptemplate_preprocess(&$vars) { $vars['title'] = 'override title';}?> Remember to clear your theme registry! With this change made and the file saved to your theme, the string override title will appear, substituted for the original $title value. Making New Variables Available The preprocess function also allows you to define additional variables in your theme. To create a new variable, you must declare the function in the template.php file. In order for your theme to have its preprocessors recognized, the template associated with the hook must exist inside the theme. If the template does not exist in your theme, copy one and place it in the theme directory. The syntax is the same as that just used for intercepting and overriding a variable, as seen above. The ability to add new variables to the system is a powerful tool and gives you the ability to add more complex logic to your theme. Summary In this two part article we covered the basics needed to make your Drupal theme responsive to the contents and the users. By applying the techniques discussed here, you can control the theming of pages based on content, state of the page or the users viewing them. Taking the principles one step further, you can also make the theming of elements within a page conditional. The ability to control the templates used and the styling of the page and its elements is what we call dynamic theming. We covered not only the basic ideas behind dynamic theming, but also the techniques needed to implement this powerful tool. Among the items discussed at length were the use of suggestions to control template display, and the implementation of $body_classes. Also covered in this article, was the use of the preprocess function to work with variables inside your theme
Read more
  • 0
  • 0
  • 1770

article-image-copying-database-sql-server-2005-sql-server-2008-using-copy-database-wizard
Packt
24 Oct 2009
3 min read
Save for later

Copying a Database from SQL Server 2005 to SQL Server 2008 using the Copy Database Wizard

Packt
24 Oct 2009
3 min read
(For more resources on Microsoft, see here.) Using the Copy Database Wizard you will be creating an SQL Server Integration Services package which will be executed by an SQL Server Agent job. It is therefore necessary to set up the SQL Server Agent to work with a proxy that you need to create which can execute the package. Since the proxy needs a credential to workout outside the SQL 2008 boundary you need to create a Credential and a Principal who has the permissions. Creating a credential has been described elsewhere. The main steps in migration using this route are: Create an Credential Create an SQL Server Agent Proxy to work with SSIS Package execution Create the job using the Copy Database Wizard Creating the Proxy In the SQL Server 2008 Management Studio expand the SQL Server Agent node and then expand the Proxies node. You can create proxies for various actions that you may undertake. In the present case the Copy Database wizard creates an Integration Services package and therefore a proxy is needed for this. Right click the SSIS Package Execution folder as shown in the next figure. Click on New Proxy.... This opens the New Proxy Account window as shown. Here Proxy name is the one you provide which will be needed in the Copy Database Wizard. Credential name is the one you created earlier which uses a database login name and password. Description is an optional info to keep track of the proxy. As seen in the previous figure you can create different proxies to deal with different activities. In the present case a proxy will be created for Integration Service Package execution as shown in the next figure. The name CopyPubx has been created as shown. Now click on the ellipsis button along the Credential name and this brings up the Select Credential window as shown. Now click on the Browse... button. This brings up the Browse for Objects window displaying the credential you created earlier. Place a checkmark as shown and click on the OK button. The [mysorian] credential is entered into the Select Credential window. Click on the OK button on the Select Credential window. The credential name gets entered into the New Proxy Account's Credential name. The optional description can be anything suitable as shown. Place a checkmark on the SQL Server Integration Services Package as shown and click on Principals. Since the present proxy is going to be used by the sysadmin, there is no need to add it specifically. Click on the OK button to close this New Proxy Account window. You can now expand the SSIS Package Execution node of the Proxies and verify that CopyPubx has been added. There are two other proxies created in the same way in this folder. Since the SQL Server Agent is needed for this process to succeed, make sure the SQL Server Agent is running. If it has not started yet, you can start this service from the Control Panel.  
Read more
  • 0
  • 0
  • 9030

article-image-creating-and-managing-user-groups-joomla-and-virtuemart
Packt
24 Oct 2009
9 min read
Save for later

Creating and Managing User Groups in Joomla! and VirtueMart

Packt
24 Oct 2009
9 min read
User manager In Joomla!, there is one User Manager component from where you can manage the users of that site. However, for the VirtueMart component, there is another  user manager which should be used for the VirtueMart shop. To be clear about  the differences of these two user managers, let us look into both. Joomla! user manager Let us first try Joomla!'s user manager. Go to the Joomla! control panel and click on the User Manager icon or click on Site | User Manager. This brings the User Manager screen of Joomla!: We see that the users registered to the Joomla! site are listed in this screen. This screen shows the username, full name, enabled status, group that the user is assigned to, email of the user, date and time when they last visited, and user ID. From this screen, you may guess that any user can be enabled or disabled by clicking on the icon in the Enabled column. Enabled user accounts show a green tick mark in the Enabled column. For viewing the details of any user, click on that user's name in the Name column. That brings up the User:[Edit] screen: As you see, the User Details section shows some important information about the user including Name, Username, E-mail, Group, and so on. You can edit and change these settings including the password. In the Group selection box, you must select one level. The deepest level gets the highest permission in the system. From this section, you can also block a user and decide whether they will receive system  emails or not. In the Parameters section, you can choose the Front-end Language and Time Zone for that user. If you have created contact items using Joomla!'s Contacts component, you may assign one contact to this user in the Contact Information section. VirtueMart user manager Let us now look into VirtueMart's user manager. From the Joomla! control panel, select Components | VirtueMart to reach the VirtueMart Administration Panel. To view the list of the user's registered to the VirtueMart store, click on Admin | Users. This brings the User List screen: As you can see, the User List screen shows the list of users registered to the shop. The screen shows their username, full name, group the user is assigned to, and their shopper group. In the Group column, note that there are two groups mentioned. One group is without brackets and another is inside brackets. The group name mentioned inside brackets is Joomla!'s standard user groups, whereas the one without brackets is VirtueMart's user group. We are going to learn about these user groups in the  next section. For viewing the details of a user, click on the user's name in Username column. That brings the Add/Update User Information screen: The screen has three tabs: General User Information, Shopper Information, and Order List. The General User Information tab contains the same information which was shown in Joomla!'s user manager's User: [Edit] screen. The Shopper Information tab contains shop related information for the user: The Shopper Information section contains: a vendor to which the user is registered the user group the user belongs to a customer number/ID the shopper group Other sections in this tab are: Shipping Addresses, Bill To Information, Bank Account, and any other section you have added to the user registration or account maintenance form. These sections contain fields which are either available on the registration or account maintenance form. If the user has placed some orders, the Order List tab will list the orders placed by that user. If no order has been placed,  the Order List tab will not be visible. Which user manager should we use? As we can see, there is a difference between Joomla!'s user manager and VirtueMart's user manager. VirtueMart's user manager shows some additional information fields, which are necessary for the operation of the shop. Therefore, whenever you are managing users for your shop, use the user manager in the VirtueMart component, not Joomla!'s user manager. Otherwise, all customer information will not be added or updated. This may create some problems in operating the VirtueMart store. User Groups Do you want to decide who can do what in your shop? There is a very good way for doing that in Joomla! and VirtueMart. Both Joomla! and VirtueMart have some predefined user groups. In both cases, you can create additional groups and assign permission levels to these groups. When users register to your site, you assign them to one of the user groups. Joomla! user groups Let us first look into Joomla! user groups. Predefined groups in Joomla! are  described below: User Group Permissions Public Frontend Registered Users in this group can login to the Joomla! site and view the contents, sections, categories, and the items which are marked only for registered users. This group has no access to content management. Author Users in this group get all the permissions the Registered group has. In addition to that, users in this group can submit articles for publishing, and can edit their own articles. Editor Users of this group have all the above permissions, and also can edit articles submitted by other users. However, they cannot publish the contents. Publisher Users in this group can login to the system and submit, edit, and publish their own content as well as contents submitted by other users. Public Backend Manager Users in this group can login to the administration panel and manage content items including articles, sections, categories, links, and so on. They cannot manage users, install modules or components, manage templates and languages, and access global configurations. Users in this group can access some of the components for which the administrator has given permission. Administrator In addition to content management, users in this group can add a user to Super Administrator group, edit a user, access the global configuration settings, access the mail function, and manage/install templates and language files. Super Administrator Users in this group can access all administration functions. For every site, at least one should be in this group to perform global configurations. You cannot delete a user in this group or move him/her to another group. As you can see, most of the users registering to your site should be assigned to the Registered group. By default, Joomla! assigns all newly registered users to the Registered group. You need to add some users to the Editor or Publisher group if they need to add or publish content to the site. The persons who are managing the shop should be assigned to other Public Backend groups such as Manager, Administrator or Super Administrator. VirtueMart user groups Let us now look into the user groups in VirtueMart. To see the user groups, go to VirtueMart's administration panel and click on Admin | User Groups. This shows the User Group List screen: By default, you will see four user groups: admin, storeadmin, shopper, and demo. These groups are used for assigning permissions to users. Also, note the values in the User Group Level column. The higher the value in this field, the lower the permissions assumed for the group. The admin group has a level value of 0, which means it has all of the permissions, and of course, more than the next group storeadmin. Similarly, storeadmin group has more permissions than the shopper group. These predefined groups are key groups in VirtueMart, and you cannot modify or delete these groups. These groups have the following permissions: Group Permissions admin This group has permissions to use all of the modules except checkout and shop. The admin group does not need these because admin users usually do not shop in their store. storeadmin This group has fewer permissions than admin group. Users in this group can access all the modules except the admin, vendor, shop, and checkout modules. They cannot set the global configurations for the store, but can add and edit payment methods, products, categories, and so on. shopper This group has the least permission among the three key groups. By default, users registered to the shop are assigned to this group. Users in this group can fully access the account module, and can use some functions of the shop, coupon, and checkout modules. demo This is a demo group created by default so that administrators can test and play with it. For most of the shops, these four predefined groups will be enough to implement appropriate permissions. However, in some cases you may need to create a new user group and assign separate permissions to that group. For example, you may want to employ some people as store managers who will add products to the catalog and manage the orders. They cannot add or edit payment methods, shipping methods, or other settings, except product and orders. If you add these people to the storeadmin group then they get more permissions than required. In such situations, a good solution is to create a new group, add selected user accounts to that group, and assign permissions to that group. Creating a new user group For creating a new user group, click on the New button in the toolbar on the User Group List screen. This brings Add/Edit a User Group screen: In the Add/Edit a User Group screen, enter the group's name and group level. You must type a higher value than existing groups (for example, 1000). Click on the Save icon to save the user group. You will now see the newly created user group in the User Group List screen.
Read more
  • 0
  • 0
  • 8734

article-image-miro-interview-nicholas-reville
Packt
24 Oct 2009
6 min read
Save for later

Miro: An Interview with Nicholas Reville

Packt
24 Oct 2009
6 min read
Kushal Sharma: What is the vision behind Miro? Nicholas Reville: There's an opportunity to build a new, open mass medium of online television. We're developing the Miro Internet TV platform so that watching Internet video channels will be as easy as watching TV and broadcasting a channel will be open to everyone. Unlike traditional TV, everyone will have a voice. KS: Does PCF finance the entire project or do you have any other contributors? NR: We have tons of help from volunteers – translating the software, coding, testing, and providing user support. We would not be able to do nearly enough without our community. KS: Are the developers full-time PCF employees or is it similar to other Open Source projects where people voluntarily contribute to the community in their spare-time? NR: We have 6 full-time developers and also volunteers. We're a hybrid model, like Mozilla. KS: Please highlight the most crucial features of Miro, and the idea behind having those features as part of this application. NR: The most crucial feature of Miro is the ability to download and play video RSS feeds. It's a truly open way to distribute video online. Using RSS means that creators can publish with any company they want and users can bring together video from multiple sources into one application. KS: How many languages is Miro translated into? NR: Miro is at least partially translated into more than 40 languages, but we always need helping revising and improving the translations. KS: How is Miro different from other players from the technological perspective? NR: Above all, Miro is open-source. That means that anyone can work on the code, improve, and customize it. Beyond this, Miro is unique in a number of ways. It runs on Mac, Windows, and Linux. It can play almost any video format. And it has more HD content available than any other Internet TV application. KS: Are the Torrent download capabilities as well developed as any other standalone Bit Torrent Client? Please tell us something more about it's download capabilities, the share ratio, configurable upload limits while downloading the torrents etc. compared to other software? NR: Our current version of Miro keeps the BitTorrent capabilities very simple and doesn't provide many options. We think that most users don't even notice when they are downloading a torrent feed, however, we want to expand our options and features for power users in future versions – expect much more bit torrent control in 3 months or so. KS: What type of support do you have for Miro? NR: Most of our support is provided user-to-user in the discussion forums – they are very useful, actually. In addition, because we are an open project, anyone can file a bug or even fix a bug. In the long-term this means we will have a more stable user experience than closed competitors. KS: With a host of TV channels and video content going online, viewers could really use a common solution for all their media needs rather than keeping tabs on multiple sources. How do you see Miro being instrumental in providing this? NR: We think that an open platform for video is the only way to create a unified experience for video. Miro is the only really open Internet video solution right now and we think we have a crucial role to play in unifying Internet TV in an open way. KS: Does Miro download Internet TV programs and store it on the hard disk or does it stream live media like any other online service? NR: For now, Miro downloads everything that's watched. This is useful in two key ways: first, you can watch HD video with no skipping or buffering delays. Second, you can move those files onto any external device, with no DRM or other restrictions. In the future we may add a streaming option for some special cases, or the ability to start watching while the download is in progress. KS: Subscription-free content is a great gift that viewers get with Internet TV, however, bandwidth issues could be a concern for some users. What minimum bandwidth requirements would you suggest for satisfactory Internet TV performance on Miro? Furthermore, does Miro have an alternate solution for users having low Internet bandwidth? NR: Miro actually works better than most Internet video solutions for low bandwidth users. On a dial-up connection, streaming video solutions are unusable. Miro will download videos in those circumstances – it may happen slowly, but once you have the video you can watch it full speed with no skipping. KS: I remember a statement on the PCF site saying “Miro is designed to eliminate gatekeepers”. Could you please elaborate on this? NR: Miro works with open standards and is designed to be decentralized, like the web. That means that users can use Miro to connect directly to any video publisher – they don't need our permission and the files don't travel through our servers. Companies like Joost design their software to be highly centralized so that they can control both users and creators. It's time to leave that model behind. KS: So far, what has the response been like? NR: Response has been great. Last month alone, we had more than 200,000 downloads and we've been growing with each release. I expect that when we release version 1.0 in November we'll see even faster growth. KS: What are your future plans for Miro in terms of releases, updates, functionality, etc.? NR: After version 1.0 is released, we'll be making major changes to Miro to improve performance and add an extension system that will give people new ways of customizing the software to fit their needs. KS: To me, Miro’s agenda is a lot more than simply creating a good player. You’re attempting to change the face of Internet Video and the way it’s being hosted right now. How would you describe the future of Miro and Internet Video to our readers? NR: We want Miro to push online video in an open direction. We're hoping to build the best video experience possible, something that can be a true substitute for traditional television. But that doesn't mean we want to control the future of online video – we want other people to build open video distribution platforms as well. Openness is vital to the future of our mass media. KS: What other projects is the PCF involved in? NR: Right now, PCF is exclusively focused on making video more open and Miro is at the center of that. KS: Thank you for your time Nicholas, and good luck developing Miro!
Read more
  • 0
  • 0
  • 2638

article-image-service-versioning-soa
Packt
24 Oct 2009
15 min read
Save for later

Service Versioning in SOA

Packt
24 Oct 2009
15 min read
Making a Change For the next few months, the Center of Excellence paid off. Projects were identifying services early in the lifecycle. Those same projects were successfully identifying other potential consumers of these new services. Implementation technologies were being chosen correctly and interface design was being properly done. Most importantly, everyone felt the SOA effort was on track. By this time, it had been almost two years since Spencer's team developed the Customer Information Service for the auto insurance and home insurance divisions. While these two groups were very happy with the results, no additional teams had leveraged it. Outside of the annuity project, this wasn't a case of projects going in another direction; it was more due to lack of opportunities. That was about to change. Spencer was eating lunch in the cafeteria when Ramesh walked up. "Mind if I join you, Spencer?" "Hey Ramesh, it's been quite some time. Go ahead and pull up a chair." "Do you remember two years ago you tried to convince Ryan to use your Customer Information Service?" "I sure do. I didn't want to show my face in the annuity area for about a month after that. He really wasn't very receptive to the idea." "Well, I have some good news and some better news for you. The good news is that about six months later, Ryan decided to leave Advasco. The better news is that we've now got a major initiative to revamp a number of our systems in the annuity department. I'd like to take advantage of the Customer Information Service as part of that effort." "That's good news Ramesh. I didn't harbor any resentment towards Ryan, but I'm certainly happy about having another potential consumer for the Customer Information Service. I'll put you in touch with the service manager for it." "Thanks Spencer. That would be great. We're just getting started on our architecture, so the timing is perfect." "Let me know if you run into any problems. I'm still part of the SOA Center of Excellence, so it's still my job to make sure it goes well!" Spencer put Ramesh in contact with the service manager for the Customer Information Service, Maria. Maria had recently transferred over after her work on the account maintenance effort, and now had responsibilities for the Customer Information Service. In the meeting with Ramesh, she brought her technical lead, Craig, with her "Spencer told me that you're interested in utilizing the Customer Information Service in some of the new systems you're building in the annuity department, Ramesh." "That's right. We're rewriting a number of our systems, and based on what I remembered from Spencer two years ago, I thought we might be able to leverage the service." "Great, I'd be happy to help you out. This is Craig, the technical lead who covers the Customer Information Service. He's here if you've got any technical questions. Have you had a chance to review the information available in the service repository?" "I have. I reviewed the service interface, and while it certainly looks like there's enough there to warrant using the service rather than building our own, there's also a number of additional things that we'll need." Craig responded, "What kind of changes are you looking for? Are there new operations that you need that are specific to the annuity area?" Ramesh said, "There are two or three operations that we'd like to see, but most of the changes are actually in the message schemas for the existing operations. There are some additional attributes that we need, and some of the relationships between the attributes are different in our representation." For the rest of the meeting, Ramesh and Craig went through the changes that Ramesh wanted to be made to accommodate his needs. In the end, it was clear that some changes to the existing schemas would have to be made. Maria asked, "We're going to need to go back and look over these changes, along with the integration approach for your existing database. What does the schedule for your efforts currently look like?" Ramesh replied, "We're still in the initial stages of planning, which is why I wanted to make sure I talked to you now. Right now, the project sponsors would like to have something within six months, but they also know that nine months is far more likely. Since I have some flexibility in my schedule, why don't you take a week to look into the effort required for the changes, and let's work out the schedule then. Does that work for you?" "That works for me. We'll get back to you next week with what we think it will take to implement the changes." On the way back to their desks, Craig commented to Maria, "You know, while I don't have any concerns about getting the work done for Ramesh, I do have some concerns on how these changes are going to impact our existing consumers. Some of these changes are going to break the existing interfaces." Maria said, "That is a concern. I know that there aren't any resources available to do any work on the home insurance side of things. Any suggestions on how we should handle this?" Craig said, "Well, we definitely should make the existing consumers aware that a change is going to be made and at least get a clear idea of what the impact will be. If you can take care of that, I can take this to Spencer and the SOA Center of Excellence, and see what suggestions they have." "That sounds like a good plan to me," replied Maria Over the next week, the Customer Information Service team did the analysis required to estimate how long the changes would take to implement. Maria used the communication features of the service registry/repository to push out a message to the existing consumers about the pending change, and as she suspected, the biggest problem was going to be the home insurance system. Due to other priorities, the earliest they could even begin to make changes to their consumer would be nine months from now, potentially three months after the service needed to go live. Craig met with Spencer and explained the problem to him. Spencer agreed to facilitate a decision-making session to explore the different options. Representatives from all of the existing consumers were there, along with Ramesh, Craig, and Maria Spencer started the meeting, "I'm sure all of you saw the notification from Maria last week that some changes are necessary to the Customer Information Service in order to support its usage by the annuity department. The problem that we face is that these changes will break the existing consumers of the service, and not all of you can make the changes to your systems in the currently proposed timeframe. Let's start out by listing all possible options, regardless of whether we all presently agree or disagree on their viability." Craig started out, "Well, if we're listing all possible options, the first one is toupdate the service, and then get whatever push we need from management to get resources allocated to the consuming systems so they can make the changes in the time required." Maria replied, "Come on Craig, you know that we can't just pull resources off projects that easily." Jason, from the auto insurance department, added, "Aren't all of these changes a result of the annuity department? Why can't they just include modifying our applications within their project scope? They already have resources allocated to their project." Paul, from the home insurance department, replied, "Do you really want some developers that have never seen your application before mucking around in your code? I know I don't." Spencer said, "Let's remember, we're listing all options, regardless of whether we all know that the option won't fly. We want to make sure we've explored all of the options. I'm going to just leave this as one option, since we still wind up with the same result, regardless of where the resources come from. I'll capture the concerns about the option." Paul, from the home insurance group, added, "Okay, here's another option. Why don't we leave the existing service in place, and simply have the annuity project write a new service that just they use. Then, none of us using the existing service would be impacted." Craig replied, "That's true, but isn't that going against everything we're trying to do with SOA? I thought we were trying to avoid redundant implementations of the same capability." Spencer replied, "Duly noted, Craig. Just as with the last option, let's keep it on the board, and I'll make sure that your concerns are captured. Paul, that option actually triggered another one in my mind. In addition to having Maria's team write the new service for the annuity system, why couldn't they also keep the existing version of the service available in production for the rest of you? You can then migrate as your schedules allow." Paul and Jason both replied in tandem, "That would work for us!" Maria jumped into the conversation, "While I'm sure it would, that sets a very dangerous precedent for my team. How many versions of the service are we going to have to maintain? While it's a little bit better when all the implementations are owned by one team, we still have multiple implementations." Jason then asked, "Isn't there a way to make the new service backwards compatible with the messages associated with the old service? That way, Maria's teamwould only have one implementation, but we could each continue to use our existing interface." Spencer replied, "That's a very good question Jason. While we all agree that the service interface needs to change to support the annuity department's requirements, I don't know that any of us have thought about whether we can easily transform messages associated with the previous version to messages that will work with the new version, and vice versa. Craig, you're the one most familiar with the new proposed schemas. Do you think we could leverage XSLT to apply transformations for backward compatibility?" "Yes, I think it's possible. The only concern I have is what impact this will have on the service implementation. Working with XSLT within Java code isn't the easiest thing to do, and as we make future modifications, that's just going to get uglier and uglier." Spencer said, "There's another option for that. A year ago, we put some XML appliances in place for security purposes. I know they have XSLT capabilities and they're already in the request path." Craig replied, "Of all the options, I think that one would work out the best. I really don't like the idea of maintaining multiple versions of the service, and having to maintain all of that XSLT code within the service is only slightly better. Allowing the annuity group to write their own goes against everything we're trying to do with SOA." Spencer said, "Well, we know where Craig stands. Are there any other options that we should look into? No? Well, what does everyone think?" Paul was first, "We know that we're not going to find resources to make the changes in all of the consumers at the same time, so that option is out. Likewise, it doesn't make sense for Ramesh's team to write their own service given our SOA goals, so that one is out, too. As for whether Maria's team maintains two versions of the service or utilizes some transformations somewhere, it really doesn't matter to me. From my perspective, both options give me the freedom to migrate at the time that works best for me." Jason immediately added, "I agree with everything Paul just said." Ramesh then offered his opinion, "Well, I certainly know that I don't want to give up any of my developers to work on Jason's and Paul's systems. We need every developer we can get right now. As for writing our own service, we've already been down that path two years ago, and now we're obviously changing the system again. If we had migrated to the service earlier, it would be one less thing that we had to touch as part of these changes. As long as Maria's team delivers my service on time for my projects, it doesn't matter to me what Maria's team chooses to do on their side." Spencer replied, "Well Maria, it looks like everyone else thinks that we need a solution that will allow all of the consumers to continue to use their existing interfaces or the new one, but the details of how that happens is completely up to you and Craig." Maria said, "Let's not jump to conclusions yet. If I'm going to maintain multiple versions, I need some kind of guarantee that the existing consumers will eventually migrate to the new version. If my team allows continuous use of the old interface for 12 months from the time the new interface goes live, would that be an adequate time to complete whatever modifications are necessary?" Jason and Paul thought about it and decided that this was reasonable. For the past three years, they'd averaged an update every nine months. Maria said, "I'll make sure to remind you, early and often, that the old version and its associated interfaces are going to be decommissioned. In the meantime, I'd like to first get the new version built. I'm going to need to keep both versions around initially just to compare messages. Ramesh's team can begin using the new service, and…" As she was talking, she stopped mid-sentence. Spencer said, "Is there a problem, Maria?" She replied, "Well, I was just thinking, how are we going to avoid having two URL's out there? The existing consumers are using a URL that points to the XML appliances, right? We want to apply transformations to that path. What URL will Ramesh's team use? We don't want to try to apply transformations to their requests." Spencer said, "Fortunately, I don't think we'll need to do that. We'll need to talk to the team that operates the appliances to be sure, but I'm pretty sure that the appliances can apply processing based upon incoming attributes on the message. As long as we can determine which requests came from which consumer based on the message content, we should be able to control when transformations happen, while having all the existing consumers using a single URL. We'll obviously need multiple URLs behind the intermediary, but that will be hidden from the consumers." Maria replied, "Okay, that eases some of my fears. Just make sure you find out quickly whether the appliances can handle it or not. Until we find out, can we set up a simple routing rule so that requests from the annuity group go to the new service, while the old ones stay where they are? That way, Ramesh can use the new service as soon as it is available, and Craig and his team can start working on the transformations for backward compatibility. I'd like to wait and see how that work goes before deciding whether to leave both versions out there for 12 months or to leverage the intermediary. We've never used that functionality before, and I don't want to take a chance on impacting Ramesh's schedule in case we run into difficulty. By keeping both services available in production at first, we can eliminate any dependency between the decommissioning of the old service and Ramesh's schedule." Craig added, "From my point of view, that shouldn't be a problem. I can treat the new version as if it were a completely new service, as long as the intermediary shields the consumers from that change. I will need to check how we can manage both versions at the source code level, though." Maria responded, "Good points, Craig. Taking all of this into account, I think this approach poses the least risk overall." Spencer said, "Then we're all in agreement, right? Maria's team will build a new version of the service according to the new interface, and the old interface will be available for 12 months from the time the new service is deployed. Initially, both versions will be available in production, but Maria can decommission the old service before 12 months are up, so long as the new version can be made backwards compatible via XSLT transformations. Maria will notify all consumers prior to decommissioning the old service, since regression testing will be required to ensure that backward compatibility has been maintained. She will also notify all consumers as we get closer to the 12 month cutoff when the older interface will no longer be supported." Everyone in the meeting agreed with this approach, and the teams went off and made it happen. Craig's team investigated the best way to apply the transformations, testing them using the latest Java libraries, as well as the XML appliances that Advasco had recently installed. They found that the XML appliances performed very well, and kept the programming model of the service very clean. While the Java libraries performed satisfactorily, the resulting programming model was not as clean as the team desired. With the use of the routing rules in the appliance, they were able to remove the older version of the service from production, while still supporting the older messages for the full 12 months as promised.
Read more
  • 0
  • 0
  • 1453

article-image-vbnet-application-sql-anywhere-10-database-part-2
Packt
24 Oct 2009
3 min read
Save for later

VB.NET Application with SQL Anywhere 10 database: Part 2

Packt
24 Oct 2009
3 min read
[Read the first part of this article here] Now you can click on the Preview Data… hyperlink which opens up the Preview Data window as shown in Figure 19. The Select an object to preview field gets populated automatically to run the getData () method. When you click on the Preview button, the grey area is populated by a table showing the retrieved rows of data from the Customers table as shown in Figure 19. Figure 19 Click on the Close button in the above window. In the various tasks of the DataGridView many options are chosen by default. You may also check reordering of the column by placing a check mark in the Edit Column Reordering in Figure 18 which opens Edit Columns window as shown in Figure 20, another useful control to manipulate the columns so that the columns you want to see are the first few columns. Figure 20 You may want to edit the columns and change some of the items such as reordering of the columns, column name, column width, etc. All this can be done from this screen. For this tutorial only the columns width was changed. A label was added and its text was changed to, "Demo 10 Database Customers" as shown in Figure 21. Figure 21     Build the project from the main menu item, Build. Now when the program is run by clicking the Debug --> Start without debugging, or by pressing Ctrl+F5, the program runs and Form1 is displayed as shown in Figure 22. Figure 22 Figure 23 shows the properties of the dataset DsAny that is created when the data source was created. Figure 23   The schema of the above dataset is shown in Figure 24. This gets added to the project files in the Solution Explorer. Figure 24   Using the smart tasks on the CustomerBindingSource you can carry out few of the indicated tasks shown in Figure 25. Figure 25   The properties of the CustomerBindingSource are shown in Figure 26. Figure 26 The CustomerTableAdapter directly connects to the database and it has its own properties window as shown in Figure 27. You will be able to edit queries in the dataset designer, add query, etc using the hyperlinks at the bottom of the properties window. Figure 27 Alternatively you will be able to carry out similar tasks from the smart tasks on the CustomerTableAdapter component in the component tray as shown in Figure 28. In Microsoft applications, you have more than one way of carrying out a task. Figure 28 The Object Browser shown in Figure 29 for this project shows the various data related classes that are used in the application working behind scenes as not a single line of code was explicitly used for this form to display the data. Figure 29  
Read more
  • 0
  • 0
  • 3469
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 $19.99/month. Cancel anytime
article-image-vbnet-application-sql-anywhere-10-database-part-1
Packt
24 Oct 2009
4 min read
Save for later

VB.NET Application with SQL Anywhere 10 database: Part 1

Packt
24 Oct 2009
4 min read
SQL Anywhere 10 SQL Anywhere 10 is the latest version of Sybase's feature rich SQL Anywhere database technology. It is highly scalable from the small foot-print UltraLite database all the way to its enterprise server with gigabytes of data. It is a comprehensive database package with built-in support for a wide range of applications, including session based synchronization; data exchange with both relational and non-relational data bases; secure store and forward messaging; messaging with FTP and email; and asynchronous access to mobile web services. You may download an evaluation version of the software and take it for a test drive. Sybase Central is a graphical database management interface to the database and its various supporting applications. The integration features are used in this article to create a Windows application retrieving data from the SQL Anywhere 10’s demonstration database, a database which is a part of the default installation of the developer edition. Overview of SQL Anywhere 10 From Sybase Central you can connect to the demo database quite easily by clicking on the Connections menu item and choosing Connect with SQL Anywhere 10. Figure 1 shows the SQL Anywhere management interface, Sybase Central. Using this interface you may also create an ODBC DSN by following the trail; Tools --> SQL Anywhere 10 --> open ODBC Administrator. Figure 1   It is very easy to connect to the database using the ODBC driver which is provided with the default installation of this product. The Figure 2 shows the User DSN installed with the default installation in the ODBC Data Source Administrator window. Figure 2 The Username is DBA and the Password is sql (case sensitive) for the demo database, demo.db. Please refer to the article, "Migrating from Oracle 10G XE to SQL Anywhere 10" which describes connecting to the demo database in detail. Figure 3 shows the demo database and its objects. Figure 3 VB.NET Windows Application We will create an ASP.NET 2.0 Windows application called SqlAny. We will create forms which display retrieved data from a table on the database as well as from a stored procedure after accepting a parameter passed to the stored procedure interactively. The Figure 4 shows the details of the project in the Solution Explorer as well as the Object Browser. Figure 4 Accessing SQL Anywhere Explorer SQL Anywhere Explorer is a component of SQL Anywhere that lets you connect to SQL Anywhere and UltraLite  databases from Visual Studio .NET. From the View menu of Visual Studio, you can access the SQL Anywhere Explorer as shown in Figure 5 - SQL Anywhere 10 is integrated with Visual Studio (both 1.1 and 2.0 versions). Figure 5   Alternatively, you can access SQL Anywhere Explorer from the Tools menu item as shown in Figure 6. In this case the Sybase Central management interface opens in a separate window. Interactive SQL is another of SQL Anywhere 10's tools for working with SQL queries on this database. Figure 6   When you click on SQL Anywhere Explorer from the View menu, you will be lead to the following window shown in Figure 7 which allows you to establish a data connection. Figure 7 Click on the drop-down, Add Connection, which opens the window shown in Figure 8 where you will be given a choice of two connections that you may connect to, SQL Anywhere or UltraLite. These are both databases. Both can run on mobile devices, but UltraLite has a smaller footprint. Figure 8 By choosing to connect to SQL Anywhere you invoke the authentication window for making the connection, as shown in Figure 9. The Username is DBA and the Password is sql. After entering these values you can get to the ODBC DSN mentioned earlier, from the drop-down. You may also test the connectivity which you see as being a success, for the entered values of Username, Password, and ODBC DSN. Figure 9   Visual Studio makes a data connection as shown in Figure 10. The nodes for Tables, Views, and Procedures are all expanded in this figure showing all the objects that can be accessed on this database. Since we logged in as DBA, all permissions are in place. Figure 10 Before the connection is made, SQL Anywhere starts up as shown in Figure 11. This message console gets minimized and stays up in the system tray of the desktop. This can be restored and closed by activating the icon in the tray.   Figure 11
Read more
  • 0
  • 0
  • 8913

article-image-working-simple-associations-using-cakephp
Packt
24 Oct 2009
5 min read
Save for later

Working with Simple Associations using CakePHP

Packt
24 Oct 2009
5 min read
Database relationship is hard to maintain even for a mid-sized PHP/MySQL application, particularly, when multiple levels of relationships are involved because complicated SQL queries are needed. CakePHP offers a simple yet powerful feature called 'object relational mapping' or ORM to handle database relationships with ease.In CakePHP, relations between the database tables are defined through association—a way to represent the database table relationship inside CakePHP. Once the associations are defined in models according to the table relationships, we are ready to use its wonderful functionalities. Using CakePHP's ORM, we can save, retrieve, and delete related data into and from different database tables with simplicity, in a better way—no need to write complex SQL queries with multiple JOINs anymore! In this article by Ahsanul Bari and Anupom Syam, we will have a deep look at various types of associations and their uses. In particular, the purpose of this article is to learn: How to figure out association types from database table relations How to define different types of associations in CakePHP models How to utilize the association for fetching related model data How to relate associated data while saving There are basically 3 types of relationship that can take place between database tables: one-to-one one-to-many many-to-many The first two of them are simple as they don't require any additional table to relate the tables in relationship. In this article, we will first see how to define associations in models for one-to-one and one-to-many relations. Then we will look at how to retrieve and delete related data from, and save data into, database tables using model associations for these simple associations. Defining One-To-Many Relationship in Models To see how to define a one-to-many relationship in models, we will think of a situation where we need to store information about some authors and their books and the relation between authors and books is one-to-many. This means an author can have multiple books but a book belongs to only one author (which is rather absurd, as in real life scenario a book can also have multiple authors). We are now going to define associations in models for this one-to-many relation, so that our models recognize their relations and can deal with them accordingly. Time for Action: Defining One-To-Many Relation Create a new database and put a fresh copy of CakePHP inside the web root. Name the database whatever you like but rename the cake folder to relationship. Configure the database in the new Cake installation. Execute the following SQL statements in the database to create a table named authors, CREATE TABLE `authors` ( `id` int( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `name` varchar( 127 ) NOT NULL , `email` varchar( 127 ) NOT NULL , `website` varchar( 127 ) NOT NULL ); Create a books table in our database by executing the following SQL commands: CREATE TABLE `books` ( `id` int( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `isbn` varchar( 13 ) NOT NULL , `title` varchar( 64 ) NOT NULL , `description` text NOT NULL , `author_id` int( 11 ) NOT NULL ) Create the Author model using the following code (/app/models/authors.php): <?php class Author extends AppModel{ var $name = 'Author'; var $hasMany = 'Book';} ?> Use the following code to create the Book model (/app/models/books.php): <?phpclass Book extends AppModel{ var $name = 'Book'; var $belongsTo = 'Author';}?> Create a controller for the Author model with the following code: (/app/controllers/authors_controller.php): <?phpclass AuthorsController extends AppController { var $name = 'Authors'; var $scaffold;}?>   Use the following code to create a controller for the Book model (/app/controllers/books_controller.php): <?php class BooksController extends AppController { var $name = 'Books'; var $scaffold; } ?> Now, go to the following URLs and add some test data: http://localhost/relationship/authors/ and http://localhost/relationship/books/ What Just Happened? We have created two tables: authors and books for storing author and book information. A foreign-key named author_id is added to the books table to establish the one-to-many relation between authors and books. Through this foreign-key, an author is related to multiple books, as well as, a book is related to one single author. By Cake convention, the name of a foreign-key should be underscored, singular name of target model, suffixed with _id. Once the database tables are created and relations are established between them, we can define associations in models. In both of the model classes, Author and Book, we defined associations to represent the one-to-many relationship between the corresponding two tables. CakePHP provides two types of association: hasMany and belongsTo to define one-to-many relations in models. These associations are very appropriately named: As an author 'has many' books, Author model should have hasMany association to represent its relation with the Book model. As a book 'belongs to' one author, Book model should have belongsTo association to denote its relation with the Author model. In the Author model, an association attribute $hasMany is defined with the value Book to inform the model that every author can be related to many books. We also added a $belongsTo attribute in the Book model and set its value to Author to let the Book model know that every book is related to only one author. After defining the associations, two controllers were created for both of these models with scaffolding to see how the associations are working.
Read more
  • 0
  • 0
  • 7846

article-image-development-login-management-module-and-comment-management-module
Packt
24 Oct 2009
12 min read
Save for later

Development of Login Management Module and Comment Management Module

Packt
24 Oct 2009
12 min read
Lets get started right away. Developing the Login Management Module Even though Login and session handling are separate functionalities from User management, they depend on the same table—user. Also, the functionalities are more alike than different. Hence, instead of creating a new Controller, we will be using the UserController itself as the Controller for the Login module. Keeping this point in mind, let us look at the steps involved in developing the Login Management, which are: Creating the Login page Implementing the Authentication Method Setting up the Session Applying Authorization Leaving aside the first step, all other steps mainly focus on the Controller. Here we go. Creating the Login Page We need a login page with text boxes for user name and password in which users can put their credentials and submit to the login authenticator (fancy name for the action method that will contain the logic to authenticate the user). That's what we are going to create now. The convention for any website is to show the login page when the user enters the URL without any specific page in mind. RoR also follows this convention. For example, if you enter the URL as http://localhost:3000/user, it displays the list of users. The reason is that the index action method of the UserController class calls the list method whenever the aforementioned URL is used. From this, we can understand two things—first, the default action method is index, and second, the first page to be shown is changeable if we change the index method. What we need is to show the login page whenever a user enters the URLhttp://localhost:3000/user. So let's change the index method. Open theuser_controller.rb file from the app/views/user folder and remove all the statements from the body of the index method so that it looks like as follows: def indexend Next, let us create an index.rhtml file, which will be shown when the index method is called. This file will be the login page. In the app/views/user folder, create an index.rhtml file. It will be as follows <%= form_tag :action=> 'authenticate'%><table ><tr align="center" class="tablebody"><td>User name:</td><td><%= text_field("user", "user_name",:size=>"15" ) %></td></tr><tr align="center" class="tablebody"><td>Password:</td><td><%= password_field("user","password",:size=>"17" ) %></td></tr><tr align="center" class="tablebody"><td></td><td><input type="submit" value=" LOGIN " /></td></tr></table> It uses two new form helpers—text_field and password_field. The text_field creates a text field with the name passed as the parameter, and the password_field creates a password field again with the name passed as the parameter. We have passed the authenticate method as the action parameter so that the form is submitted to the authenticate method. That completes the login page creation. Next, we will work on the authenticate method. Implementing the Authenticate method Implementing the Authenticate method Authenticating a user essentially means checking whether the user name and password given by the user corresponds to the one in database or not. In our case, the user gives us the user name and password through the login page. What we will be doing is checking whether the user is in database and does the password that we got corresponds to the password stored in the database for the user? Here, we will be working on two levels: Model Controller We can put the data access part in the action method that being the Controller itself. But it will create problems in the future if we want to add something extra to the user name/password checking code. That's why we are going to put (or delegate) the data access part into Model. Model We will be modifying the User class by adding a method that will check whether the user name and password provided by the user is correct or not. The name of the method is login. It is as follows: def self.login(name,password)find(:first,:conditions => ["user_name = ? and password =?",name, password])end It is defined as a singleton method of the User class by using the self keyword. The singleton methods are special class-level methods. The conditions parameter of the find method takes an array of condition and the corresponding values. The find method generates an SQL statement from the passed parameters. Here, the find method finds the first record that matches the provided user_name and password. Now, let us create the method that the Controller will call to check the validity of the user. Let us name it check_login. The definition is as follows: def check_loginUser.login(self.user_name, self.password)end This function calls the login method. Now if you observe closely, check_login calls the login function. One more point to remember—if a method 'test' returns a value and you call 'test' from another method 'test1,' then you don't need to say 'return test' from within 'test1'.The value returned from 'test' will be returned by 'test1' implicitly. That completes the changes to be done at the Model level. Now let us see the changes at the Controller-level. Controller In the Controller for User—UserController—add a new method named authenticate. The method will first create a User object based on the user name and password. Then it will invoke check_login on the newly created User object. If check_login is successful, that is, it does not return nil, then the user is redirected to the list view of Tales. Otherwise, the user is redirected to the login page itself. Here is what the method will look like: def authenticate@user = User.new(params[:user])valid_user = @user.check_loginif logged_in_userflash[:note]="Welcome "+logged_in_user.nameredirect_to(:controller=>'tale',:action => "list")elseflash[:notice] = "Invalid User/Password"redirect_to :action=> "index"endend The redirect_to method accepts two parameters—the name of the Controller and the method within the Controller. If the user is valid, then the list method of TaleController is called, or in other words, the user is redirected to the list of tales. Next, let us make it more robust by checking for the get method. If a user directly types a URL to an action, then the get method is received by the method. If any user does that, we want him/her to be redirected to the login page. To do this, we wrap up the user validation logic in an if/else block. The code will be the following: def authenticate if request.get?render :action=> 'index'else@user = User.new(params[:user])valid_user = @user.check_loginif valid_userflash[:note]="Welcome "+valid_user.user_nameredirect_to(:controller=>'tale',:action => 'list')else flash[:notice] = "Invalid User/Password"redirect_to :action=> 'index'endendend The get? method returns true if the URL has the GET method else it returns false. That completes the login authentication part. Next, let us set up the session. In Ruby, any method that returns a Boolean value—true or false—is suffixed with a question mark (?). The get method of the request object returns a boolean value. So it is suffixed with a question mark (?). Setting up the Session Once a user is authenticated, the next step is to set up the session to track the user. Session, by definition, is the conversation between the user and the server from the moment the user logs in to the moment the user logs out. A conversation is a pair of requests by the user and the response from the server. In RoR, the session can be tracked either by using cookies or the session object. The session is an object provided by RoR. The session object can hold objects where as cookies cannot. Therefore, we will be using the session object. The session object is a hash like structure, which can hold the key and the corresponding value. Setting up a session is as easy as providing a key to the session object and assigning it a value. The following code illustrates this aspect: def authenticateif request.get?render :action=> 'index'else@user = User.new(params[:user])valid_user = @user.check_loginif valid_usersession[:user_id]=valid_user.idflash[:note]="Welcome "+valid_user.user_nameredirect_to(:controller=>'tale',:action => 'list')elseflash[:notice] = "Invalid User/Password"redirect_to :action=> 'index'endendend That completes setting up the session part. That brings us to the last step—applying authorization. Applying Authorization Until now, we have authenticated the user and set up a session for him/her. However, we still haven't ensured that only the authenticated users can access the different functionalities of TaleWiki. This is where authorization comes into the picture. Authorization has two levels—coarse grained and fine grained. Coarse grained authorization looks at the whole picture whereas the fine grained authorization looks at the individual 'pixels' of the picture. Ensuring that only the authenticated users can get into TaleWiki is a part of coarse grained authorization while checking the privileges for each functionality comes under the fine grained authorization. In this article, we will be working with the coarse grained authorization. The best place to apply the coarse grained authorization is the Controller as it is the central point of data exchange. Just like other aspects, RoR provides a functionality to easily apply any kind of logic on the Controller as a whole in the form of filters. To jog your memory, a filter contains a set of statements that need to be executed before, after (or before and after) the methods within the Controllers are executed. Our problem is to check whether the user is authenticated or not, before any method in a Controller is executed. The solution to our problem is using a 'before filter'. But we have to apply authorization to all the Controllers. Hence, the filter should be callable from any of the Controller. If you look at the definition of a Controller, you can find such a place. Each Controller is inherited from the ApplicationController. Anything placed in ApplicationController will be callable from other Controllers. In other words, any method placed in ApplicationController becomes global to all the Controllers within your application. So, we will place the method containing the filter logic in ApplicationController. To check whether a user is authentic or not, the simplest way is to check whether a session exists for that person or not. If it exists, then we can continue with the normal execution. Let us name it check_authentic_user. The implementation will be as follows: def check_authentic_userunless session[:user_id]flash[:notice] = "Please log in"redirect_to(:controller => "user", :action =>"index")endend It checks for the user_id key in a session. If it is not present, the user is redirected to the login page. Place the code in the application.rb file as a method of ApplicationController. Next, let us use it as a filter. First, we will tell UserController to apply the filter for all the action methods except index and authenticate methods. Add the following statement to the UserController. It should be the first statement after the starting of the Controller class. class UserController < ApplicationControllerbefore_filter :check_authentic_user, :except =>[ :index, :authenticate ]::end Similarly, we will place the filter in other Controllers as well. However, in their case, there are no exceptions. So TaleController will have: class TaleController < ApplicationControllerbefore_filter :check_authentic_user::end GenreController and RoleController will be the same as TaleController. Thus, we have completed the 'applying authorization' part for the time being. Now, let's tie up one loose end—the problem of adding a new tale. Tying Up the Loose Ends When we developed the User management, the Tale management was affected as the tales table has a many-to-one relationship with the users table. Now we can solve the problem created by the foreign key reference. First, open the user.rb file and add the following statement indicating that it is at the 'one' end of the relationship: has_many :tale After addition of the statement, the class will look like the following: class User < ActiveRecord::Basevalidates_presence_of :user_name, :password, :first_name,:last_name, :age, :email, :country validates_uniqueness_of :user_namevalidates_numericality_of :age validates_format_of :email, :with => /A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})Z/ibelongs_to :rolehas_many :taledef check_loginUser.login(self.name, self.password)enddef self.login(name,password)find(:first,:conditions => ["user_name = ? and password=?",name, password])endend Next, add the following statement to the tale.rb file: belongs_to :user The file will look like as follows: class Tale < ActiveRecord::Basevalidates_presence_of :title, :body_text, :sourcebelongs_to:genrebelongs_to :userend Next, open the tale_controller.rb file. In the create method, we need to add the user's id to the tale's user id reference so that the referential integrity can be satisfied. For that, we will get the current user's id from the session and set it as the value of the user_id attribute of the tale object. The create method will look like as follows, after doing the changes: def create @tale = Tale.new(params[:tale])@tale.genre_id=params[:genre]@tale.user_id=session[:user_id]@tale.status="new" if @tale.saveflash[:notice] = 'Tale was successfully created.'redirect_to :action => 'list'elserender :action => 'new'endend That's it. The 'loose ends' related to the User management are tied up. Now let us move onto the Comment Management module.
Read more
  • 0
  • 0
  • 1544

article-image-why-do-we-need-specialist-security-distros
Packt
24 Oct 2009
4 min read
Save for later

Why Do We Need Specialist Security Distros?

Packt
24 Oct 2009
4 min read
I talk with Ryan Berens, from Guardian Digital makers of EnGarde Linux, to understand their role in the Linux distribution space. EnGarde is distributed in two flavors -- one of which can be had for gratis. EnGarde is what you'd call a minimalist distribution that you'd install on your server to run critical services. It's also popular for its one-stop WebTool remote administration tool. Mayank Sharma: Why do we need a specialist security distro? Why is this better than the 'adding security apps to an existing distro on the server' approach? Guardian Digital: These platforms exist to fulfill a significant need in the market. Many users want a hardened platform because locking down a system can be both difficult and time-consuming. The challenge of creating a secure foundation requires a holistic view over all of system resources, not only at default settings, but as configurations need to change. Hardened platforms, designed and built with security from the ground up, create a much more streamlined, integrated system that ensures a system can stay secure. Bloated distro's can be very insecure by default and overcoming that initial state won't be as effective as building security in from the ground up to ensure that tools all work together to minimize access to and control over resources. Simply adding a couple applications doesn't mean they necessarily 'play' well with other apps or the OS in order to perform as securely as needed. MS: What is involved in packaging a secure distro? Is there more to it than just packaging firewall and network monitoring apps? GD: So much more. As I said in the previous answer, a strong focus is on integration and default security. There are processes that could be left open to abuse, that would otherwise get overlooked. One simple example is that EnGarde sets the ls command to have the least privilege, and doesn't allow write access to /bin/ls. Ubuntu, for example, allows write access to the command ls by default. If a user isn't aware of this, it could be a hole in their system that can be compromised. The point is that adding apps that provide some kind of security process doesn't by any means address the internal security of the platform and how it interacts with other processes and applications. Sure they help, but using them, and using them securely are two different things. How does the system treat passwords? What tools does it use for ordinary, "non-security" apps? How does it integrate them? Does it use best-practices for secure remote access? So on and so on... MS: What are the main differences between the free Community and the commercial Enterprise releases? GD: Our free community platform is really more of a "bleeding edge" platform. It is a great way for users to set up a secure server and incorporate new and secure functionality, but it isn't always in the kind of stable development that is demanded for a corporate environment. Also, EnGarde Professional comes with our portfolio of secure, business-critical applications - SMS (Secure Mail Suite) for routing and securing email from Spam/Virus's for tens of thousands of users - SurfSecure, our web enforcement filter for corporate networks, and so on. These applications aren't available for the community (and most of the time, they wouldn't need to be, not at that level of scalability). And lastly is the service and support for all users. All implementations of EnGarde Professional are fully supported by our dedicated staff of security specialists, with service options for Installation, Remote Monitoring, custom development and much more. MS: Who would be the Community Edition's primary users? Can I use it as a secure desktop OS? GD: The primary users for our Community Edition are really administrators interested in providing a secure server foundation. EnGarde Community (as well as EnGarde Professional) is solely engineered for server operations. This is not a desktop OS for running spreadsheets or playing music - this is about secure, usable functionality for your servers. Even though the corporate version is recommended, there have been numerous examples where EnGarde Community was implemented in a small office environment. MS: What Package management does EnGarde have? Do you maintain your own repository of software? GD: We utilize RPM and yes we do maintain our own repository. The platform is engineered from the ground up, and this means that we choose secure packages, and then integrate and develop them expressly with security in mind. MS: Thank you for your time Ryan and wish you luck for the future.   Some more articles by Mayank Sharma: Zen Gift of Education Making a Complete yet Small Linux Distribution
Read more
  • 0
  • 0
  • 1560
article-image-manipulating-jquery-tables
Packt
24 Oct 2009
20 min read
Save for later

Manipulating jQuery tables

Packt
24 Oct 2009
20 min read
In this article by Karl Swedberg and Jonathan Chaffer, we will use an online bookstore as our model website, but the techniques we cook up can be applied to a wide variety of other sites as well, from weblogs to portfolios, from market-facing business sites to corporate intranets. In this article, we will use jQuery to apply techniques for increasing the readability, usability, and visual appeal of tables, though we are not dealing with tables used for layout and design. In fact, as the web standards movement has become more pervasive in the last few years, table-based layout has increasingly been abandoned in favor of CSS‑based designs. Although tables were often employed as a somewhat necessary stopgap measure in the 1990s to create multi-column and other complex layouts, they were never intended to be used in that way, whereas CSS is a technology expressly created for presentation. But this is not the place for an extended discussion on the proper role of tables. Suffice it to say that in this article we will explore ways to display and interact with tables used as semantically marked up containers of tabular data. For a closer look at applying semantic, accessible HTML to tables, a good place to start is Roger Johansson's blog entry, Bring on the Tables at www.456bereastreet.com/archive/200410/bring_on_the_tables/. Some of the techniques we apply to tables in this article can be found in plug‑ins such as Christian Bach's Table Sorter. For more information, visit the jQuery Plug‑in Repository at http://jQuery.com/plugins. Sorting One of the most common tasks performed with tabular data is sorting. In a large table, being able to rearrange the information that we're looking for is invaluable. Unfortunately, this helpful operation is one of the trickiest to put into action. We can achieve the goal of sorting in two ways, namely Server-Side Sorting and JavaScript Sorting. Server-Side Sorting A common solution for data sorting is to perform it on the server side. Data in tables often comes from a database, which means that the code that pulls it out of the database can request it in a given sort order (using, for example, the SQL language's ORDER BY clause). If we have server-side code at our disposal, it is straightforward to begin with a reasonable default sort order. Sorting is most useful when the user can determine the sort order. A common idiom is to make the headers of sortable columns into links. These links can go to the current page, but with a query string appended indicating the column to sort by: <table id="my-data">   <tr>     <th class="name"><a href="index.php?sort=name">Name</a></th>     <th class="date"><a href="index.php?sort=date">Date</a></th>   </tr>   ... </table> The server can react to the query string parameter by returning the database contents in a different order. Preventing Page Refreshes This setup is simple, but requires a page refresh for each sort operation. As we have seen, jQuery allows us to eliminate such page refreshes by using AJAX methods. If we have the column headers set up as links as before, we can add jQuery code to change those links into AJAX requests: $(document).ready(function() {   $('#my-data .name a').click(function() {     $('#my-data').load('index.php?sort=name&type=ajax');     return false;   });   $('#my-data .date a').click(function() {     $('#my-data').load('index.php?sort=date&type=ajax');     return false;   }); }); Now when the anchors are clicked, jQuery sends an AJAX request to the server for the same page. We add an additional parameter to the query string so that the server can determine that an AJAX request is being made. The server code can be written to send back only the table itself, and not the surrounding page, when this parameter is present. This way we can take the response and insert it in place of the table. This is an example of progressiveenhancement. The page works perfectly well without any JavaScript at all, as the links for server-side sorting are still present. When JavaScript is present, however, the AJAX hijacks the page request and allows the sort to occur without a full page load. JavaScript Sorting There are times, though, when we either don't want to wait for server responses when sorting, or don't have a server-side scripting language available to us. A viable alternative in this case is to perform the sorting entirely on the browser using JavaScript client-side scripting. For example, suppose we have a table listing books, along with their authors, release dates, and prices: <table class="sortable">   <thead>     <tr>       <th></th>       <th>Title</th>       <th>Author(s)</th>       <th>Publish&nbsp;Date</th>       <th>Price</th>     </tr>   </thead>   <tbody>     <tr>       <td>         <img src="../covers/small/1847192386.png" width="49"              height="61" alt="Building Websites with                                                 Joomla! 1.5 Beta 1" />       </td>       <td>Building Websites with Joomla! 1.5 Beta 1</td>       <td>Hagen Graf</td>       <td>Feb 2007</td>       <td>$40.49</td>     </tr>     <tr>       <td><img src="../covers/small/1904811620.png" width="49"                height="61" alt="Learning Mambo: A Step-by-Step                Tutorial to Building Your Website" /></td>       <td>Learning Mambo: A Step-by-Step Tutorial to Building Your           Website</td>       <td>Douglas Paterson</td>       <td>Dec 2006</td>       <td>$40.49</td>     </tr>     ...   </tbody> </table> We'd like to turn the table headers into buttons that sort by their respective columns. Let us look into ways of doing this.   Row Grouping Tags Note our use of the <thead> and <tbody> tags to segment the data into row groupings. Many HTML authors omit these implied tags, but they can prove useful in supplying us with more convenient CSS selectors to use. For example, suppose we wish to apply typical even/odd row striping to this table, but only to the body of the table: $(document).ready(function() {   $('table.sortable tbody tr:odd').addClass('odd');   $('table.sortable tbody tr:even').addClass('even'); }); This will add alternating colors to the table, but leave the header untouched: Basic Alphabetical Sorting Now let's perform a sort on the Titlecolumn of the table. We'll need a class on the table header cell so that we can select it properly: <thead>   <tr>     <th></th>    <th class="sort-alpha">Title</th>     <th>Author(s)</th>     <th>Publish&nbsp;Date</th>     <th>Price</th>   </tr> </thead> To perform the actual sort, we can use JavaScript's built in .sort()method. It does an in‑place sort on an array, and can take a function as an argument. This function compares two items in the array and should return a positive or negative number depending on the result. Our initial sort routine looks like this: $(document).ready(function() {   $('table.sortable').each(function() {     var $table = $(this);     $('th', $table).each(function(column) {       if ($(this).is('.sort-alpha')) {         $(this).addClass('clickable').hover(function() {           $(this).addClass('hover');         }, function() {           $(this).removeClass('hover');         }).click(function() {           var rows = $table.find('tbody > tr').get();           rows.sort(function(a, b) {             var keyA = $(a).children('td').eq(column).text()                                                       .toUpperCase();             var keyB = $(b).children('td').eq(column).text()                                                       .toUpperCase();             if (keyA < keyB) return -1;             if (keyA > keyB) return 1;             return 0;           });           $.each(rows, function(index, row) {             $table.children('tbody').append(row);           });         });       }     });   }); }); The first thing to note is our use of the .each() method to make iteration explicit. Even though we could bind a click handler to all headers with the sort-alpha class just by calling $('table.sortable th.sort-alpha').click(), this wouldn't allow us to easily capture a crucial bit of information—the column index of the clicked header. Because .each() passes the iteration index into its callback function, we can use it to find the relevant cell in each row of the data later. Once we have found the header cell, we retrieve an array of all of the data rows. This is a great example of how .get()is useful in transforming a jQuery object into an array of DOM nodes; even though jQuery objects act like arrays in many respects, they don't have any of the native array methods available, such as .sort(). With .sort() at our disposal, the rest is fairly straightforward. The rows are sorted by comparing the textual contexts of the relevant table cell. We know which cell to look at because we captured the column index in the enclosing .each() call. We convert the text to uppercase because string comparisons in JavaScript are case-sensitive and we wish our sort to be case-insensitive. Finally, with the array sorted, we loop through the rows and reinsert them into the table. Since .append() does not clone nodes, this moves them rather than copying them. Our table is now sorted. This is an example of progressive enhancement's counterpart, gracefuldegradation. Unlike with the AJAX solution discussed earlier, we cannot make the sort work without JavaScript, as we are assuming the server has no scripting language available to it in this case. The JavaScript is required for the sort to work, so by adding the "clickable" class only through code, we make sure not to indicate with the interface that sorting is even possible unless the script can run. The page degrades into one that is still functional, albeit without sorting available. We have moved the actual rows around, hence our alternating row colors are now out of whack: We need to reapply the row colors after the sort is performed. We can do this by pulling the coloring code out into a function that we call when needed: $(document).ready(function() {   var alternateRowColors = function($table) {     $('tbody tr:odd', $table).removeClass('even').addClass('odd');     $('tbody tr:even', $table).removeClass('odd').addClass('even');   };     $('table.sortable').each(function() {     var $table = $(this);     alternateRowColors($table);     $('th', $table).each(function(column) {       if ($(this).is('.sort-alpha')) {         $(this).addClass('clickable').hover(function() {           $(this).addClass('hover');         }, function() {           $(this).removeClass('hover');         }).click(function() {           var rows = $table.find('tbody > tr').get();           rows.sort(function(a, b) {             var keyA = $(a).children('td').eq(column).text()                                                       .toUpperCase();             var keyB = $(b).children('td').eq(column).text()                                                       .toUpperCase();             if (keyA < keyB) return -1;             if (keyA > keyB) return 1;             return 0;           });           $.each(rows, function(index, row) {             $table.children('tbody').append(row);           });           alternateRowColors($table);         });       }     });   }); }); This corrects the row coloring after the fact, fixing our issue:   The Power of Plug-ins The alternateRowColors()function that we wrote is a perfect candidate to become a jQuery plug-in. In fact, any operation that we wish to apply to a set of DOM elements can easily be expressed as a plug-in. In this case, we only need to modify our existing function a little bit: jQuery.fn.alternateRowColors = function() {   $('tbody tr:odd', this).removeClass('even').addClass('odd');   $('tbody tr:even', this).removeClass('odd').addClass('even');   return this; }; We have made three important changes to the function. It is defined as a new property of jQuery.fn rather than as a standalone function. This registers the function as a plug-in method. We use the keyword this as a replacement for our $table parameter. Within a plug-in method, thisrefers to the jQuery object that is being acted upon. Finally, we return this at the end of the function. The return value makes our new method chainable. More information on writing jQuery plug-ins can be found in Chapter 10 of our book Learning jQuery. There we will discuss making a plug-in ready for public consumption, as opposed to the small example here that is only to be used by our own code. With our new plug-in defined, we can call $table.alternateRowColors(), which is a more natural jQuery syntax, intead of alternateRowColors($table). Performance Concerns Our code works, but is quite slow. The culprit is the comparator function, which is performing a fair amount of work. This comparator will be called many times during the course of a sort, which means that every extra moment it spends on processing will be magnified. The actual sort algorithm used by JavaScript is not defined by the standard. It may be a simple sort like a bubble sort (worst case of Θ(n2) in computational complexity terms) or a more sophisticated approach like quick sort (which is Θ(n log n) on average). In either case doubling the number of items increases the number of times the comparator function is called by more than double. The remedy for our slow comparator is to pre-compute the keys for the comparison. We begin with the slow sort function: rows.sort(function(a, b) {   keyA = $(a).children('td').eq(column).text().toUpperCase();   keyB = $(b).children('td').eq(column).text().toUpperCase();   if (keyA < keyB) return -1;   if (keyA > keyB) return 1;   return 0; }); $.each(rows, function(index, row) {   $table.children('tbody').append(row); }); We can pull out the key computation and do that in a separate loop: $.each(rows, function(index, row) {   row.sortKey = $(row).children('td').eq(column).text().toUpperCase(); }); rows.sort(function(a, b) {   if (a.sortKey < b.sortKey) return -1;   if (a.sortKey > b.sortKey) return 1;   return 0; }); $.each(rows, function(index, row) {   $table.children('tbody').append(row);   row.sortKey = null; }); In the new loop, we are doing all of the expensive work and storing the result in a new property. This kind of property, attached to a DOM element but not a normal DOM attribute, is called an expando.This is a convenient place to store the key since we need one per table row element. Now we can examine this attribute within the comparator function, and our sort is markedly faster.  We set the expando property to null after we're done with it to clean up after ourselves. This is not necessary in this case, but is a good habit to establish because expando properties left lying around can be the cause of memory leaks. For more information, see Appendix C.   Finessing the Sort Keys Now we want to apply the same kind of sorting behavior to the Author(s) column of our table. By adding the sort-alpha class to its table header cell, the Author(s)column can be sorted with our existing code. But ideally authors should be sorted by last name, not first. Since some books have multiple authors, and some authors have middle names or initials listed, we need outside guidance to determine what part of the text to use as our sort key. We can supply this guidance by wrapping the relevant part of the cell in a tag: <tr>   <td>     <img src="../covers/small/1847192386.png" width="49" height="61"             alt="Building Websites with Joomla! 1.5 Beta 1" /></td>   <td>Building Websites with Joomla! 1.5 Beta 1</td>   <td>Hagen <span class="sort-key">Graf</span></td>   <td>Feb 2007</td>   <td>$40.49</td> </tr> <tr>   <td>     <img src="../covers/small/1904811620.png" width="49" height="61"          alt="Learning Mambo: A Step-by-Step Tutorial to Building                                                 Your Website" /></td>   <td>     Learning Mambo: A Step-by-Step Tutorial to Building Your Website   </td>   <td>Douglas <span class="sort-key">Paterson</span></td>   <td>Dec 2006</td>   <td>$40.49</td> </tr> <tr>   <td>     <img src="../covers/small/1904811299.png" width="49" height="61"                   alt="Moodle E-Learning Course Development" /></td>   <td>Moodle E-Learning Course Development</td>   <td>William <span class="sort-key">Rice</span></td>   <td>May 2006</td>   <td>$35.99</td> </tr> Now we have to modify our sorting code to take this tag into account, without disturbing the existing behavior for the Titlecolumn, which is working well. By prepending the marked sort key to the key we have previously calculated, we can sort first on the last name if it is called out, but on the whole string as a fallback: $.each(rows, function(index, row) {   var $cell = $(row).children('td').eq(column);   row.sortKey = $cell.find('.sort-key').text().toUpperCase()                                   + ' ' + $cell.text().toUpperCase(); }); Sorting by the Author(s)column now uses the last name:     If two last names are identical, the sort uses the entire string as a tiebreaker for positioning.
Read more
  • 0
  • 0
  • 19215

article-image-migrating-ms-access-2003-data-using-oracle-sql-developer-12
Packt
24 Oct 2009
7 min read
Save for later

Migrating MS Access 2003 Data using the Oracle SQL Developer 1.2

Packt
24 Oct 2009
7 min read
Introduction Business needs often necessitate data migration from a smaller, less secure database to a higher end, faster database server with a more reliable availability. A typical scenario is the migration of data from a desktop sized database such as MS Access or Fox Pro to any other higher end database servers such as MS SQL Server, Oracle, DB2 or SQL Anywhere Server. Most of the database vendors provide tools to migrate from third party to their own database servers. In his three previous articles, the author has described the built-in tools to migrate from MS Access to SQL 2000 Server, SQL Anywhere Server, and from Oracle 10G XE to SQL Anywhere server.   In an earlier article on this site, the author showed how you may connect to an MS Access 2003 database and execute SQL statements using the Oracle SQL Developer 1.2 tool. In this tutorial the author shows you how to migrate an MS Access database to an Oracle 10G XE Server delineating all the steps involved in the migration process. Oracle SQL Developer 1.2 with this latest version is sometimes called the Migration version as it supports migrating data from three vendors (MySQL, SQL Server and MS Access) to an Oracle database. In fact, it has been designed to migrate from more than one version of MS Access. This feature was not available in the version 1.1 of this tool. Overview of this Tutorial Like in the earlier article, a simple MS Access 2003 database file will be created with just one table, a query and a linked table. This database file, about 292 KB, will be migrated to Oracle 10G XE database. Oracle 10G XE, by design, can have just one database on a computer. However, you can have separate applications by having different user schemas. Oracle 10G XE comes bundled with a sample database schema and data which can be accessed by using the credentials, username hr with a password hr. For the purposes of this example a new user will be created and his authentication will be used for creating necessary migration related schemas to be stored in a repository. This will become clear as you follow the various details and the steps. Once the ‘Repository’ is created then you can begin by capturing the metadata of the source followed by converting the captured source information into Oracle specific model where a mapping between the source data and the Oracle will be accomplished. After this process, you generate the data definition language script which will create the Oracle objects such as tables, views, etc. In the final step these tables will be populated by transferring the data from the source to Oracle 10G XE. MS Access 2003 Source An empty MS Access database file TestMigration.mdb is created in the default directory, My Documents. An Employees table will be imported, an Orders table will be linked and a TestQuery based on selecting a few columns of Employees table will be created. The Employees table and the Orders table may be found in the Northwind Database that ships with most of the MS Access versions. Creating a New User in Oracle 10G XE As described in the overview, the MS Access Database will be migrated to a User schema in Oracle 10G XE, but this requires reating this schema. Only a user with DBA privileges can create a new user. Open the Homepage of the Oracle 10G XE Server. Login with the credentials you supplied while installing the software where the user is system and the password is what you chose at that time, as shown in the next figure.   This gives you access to several of the tools that you can use to administer as well as work with database objects. Click on the icon for Administration and follow the drop-downs till you get to the menu item, Create User, as shown in the next figure. Create a new user MigrateAccess with some password that you choose and confirm. Keep the account status unlocked. This uses the default tablespace called USERS. The default user privilege does not include the DBA role but for this example, the DBA is also included by placing a check mark in this selection. Also several other system wide privileges are also granted. Please follow steps described in the earlier article for the details. The next figure shows all the details filled in. After this when you click the Create button you will have created the user, MigrateAccess. When you click the button Create, you will notice that the ‘bread crumb’ will change to Manage Database Users. You will notice that the new user MigrateAccess has been added to the list of users, as shown in the next figure. As no expiry was set for this user in the previous screen, you can notice that there is no expiry shown in the following screen. Now if you logout (remember you logged in as SYSTEM) and login with the new credentials, MigrateAccess/[chosen password] you can access all the tools on the database. Of course, all the objects (tables, views, etc) will be empty. Creating the Repository to Store Schemas Migration using this tool requires an Oracle database schema to store the Meta data it collects about the source. You will create a connection from the Oracle SQL Developer to the Oracle 10 XE, in which, you just finished creating a new user schema. This user’s schema is where the repository contents will be stored. Making a connection to the Oracle Right click on the Connections node, and from the drop-down menu select New Connection. This brings up the New / Select Database Connection (this has been described in the earlier referenced article) window. It comes up with the default connection to an Oracle database. It even recognizes the local Oracle 10G XE, capturing all its details as shown. You need to provide a Connection Name, a Username and a Password. The connection name is your choice (herein called conMigrate) and the user name and password is the same that was used while creating the new user MigrateAccess. When you click on the button ‘Test’, a (success) status message will be posted to this form above the Help button, as shown in the next figure after a little while, preceded by a little progress window. Now click on the OK button on the New / Select Database Connection window. This adds the conMigrate connection to the list of Connections as shown in the next figure. Notice that objects are all empty as we discussed earlier. Create Repository Click on the main menu item Migrate. From the drop-down, click on Repository Management –> Create Repository as shown in the next figure. This brings up the Create Repository window showing the connection conMigrate as shown in the next figure. You may connect or disconnect this from the tool as long as the authentication information is available. Now click on the Create button. This brings up the Installing Repository window which reports the various objects installed and finally shows a message “Repository Built Successfully” as shown in the next figure. Click on the Close button on this window. Now login to the Oracle 10G XE with the credentials for the user MigrateAccess, and click on the object browser. Now you see all the Tables, Views, etc in the repository as shown. You will notice that either two more windows, named captured and converted models appear below the Connections node in Oracle SQL Developer, or if they are not found in the Connections node, you may find in the submenu of the main menu, View. The next figure shows the submenus of the View menu. Connect to the Source Database Right click on the connection node and establish a new connection so that you can connect to the source database, conTestMigration as shown in the next figure. When you click the Test button you will see a message that gets posted to the screen indicating the connection was a success. Click on the Connect button. This adds the conTestMigrate connection to the list of Connections in the navigator window.
Read more
  • 0
  • 0
  • 3006

article-image-oracle-sql-developer-tool-15-sql-server-2005
Packt
24 Oct 2009
4 min read
Save for later

Oracle SQL Developer Tool 1.5 with SQL Server 2005

Packt
24 Oct 2009
4 min read
Installation and a review of some new features Installation The program [EA2 download -Early Adapter] can be downloaded from the following URL. In the present case the Windows option that comes with JDK1.5.0_06 bundled was used. The downloaded ZIP file, sqldeveloper-5073 (100MB) can be unzipped to any suitable location and from within the sqldeveloper folder you can immediately start using the program. The program can be started by double clicking the executable which has an unambiguous fat green arrow. Review of features Adjustable Look and Feel The look and feel is adjustable. You can choose between 'Windows' and 'Oracle'. After choosing 'oracle' you can choose a variety of themes. The one shown is for 'Desert Yellow'. The View Menu The View menu is better organized as shown compared to the previous version. Tools Menu Tools menu is beefed up as well as shown. External Tools The External Tools sub menu item can find existing tools (browsers, notepad, mdb files) and also using a 4 step wizard allows you to create tools, provided you know the details for accessing them. Wizards Diff Wizard allows comparing objects of same type between schema of source and destination as well update the destination based on source. Similarly the Copy Wizard allows you to copy objects from one database schema to another. Versioning Support Versioning support is another new feature in this version.SQL Developer provides integrated support for CVS [concurrent versions system] and Subversion in its source control. CVS allows repository creation on the local PC or, on a remote machine. Source files are held in folder modules. In the case of Subversion the access to the repository is by means of a connection and this is where the master copies are held, files are checked out to a local working folder. Run menu item The Run menu item also contains the debugging options as shown. In the previous version Run and Debug were two menus. Migration Menu The Microsoft Access Exporter can export from 97,2000,2002, and 2003 like in the previous version (1.2) and seems to be essentially the same as the previous version. This version can now create off line migration scripts to ASE 15 and Sybase 12 in addition to several versions of SQL Server 7,2000,2005 and MySQL (3.23,4,5) Connecting to SQL 2005 databases As described in the previous referenced articles at the beginning  you can establish a connection to the server by clicking on the Connection node (positive green sign) in the first figure. This opens New / Select Database Connection window where you will see only Oracle and Access. This is because, at this point no JDBC drivers have been specified for connecting to the other three servers, SQL Server, MySQL, and Sybase. There are two ways you can register JDBC drivers for these databases. For SQL Servers you require the jtds.jar file from the SourceForge.com web site. In the first method you need to go through Tools|Preferences|Database|Third party JDBC Drivers| to find the path to the file as shown in the next figure and use the browse key to locate the driver and add it. The driver file should be in the correct path for the application to find. In the other method that is used here, which in the opinion of the author is simpler, is to go through Help|Check Updates... This brings up the Step 1 of wizard as shown. Read the instructions in this window. Now click Next. This takes you to the next window as shown.   The needed item is already checked. Click Next. The window that comes up next shows compatible drivers for the databases. Choose items needed by placing check marks. In this tutorial both the SQL Server and MySQL drivers were chosen. Click Next. In the window that shows up agree to the licensing[GNU Public] terms after reading the terms. Click on Next in the final window of Step 4. When Step 5 "Download" windows opens the login window also opens. As these drivers are downloaded from the Oracle site, you will have to insert your Oracle login information. Step 5 screen shot is not shown. You will be adding both the JDBC drivers on the final step. Click Finish. In order to install the updates you chose, the SQL Developer 1.5 needs to restart, and it restarts when you click on Yes in the Confirm Exit window. Do you want to Migrate User Settings?  window shows up again. For this article it is a No again. The Oracle SQL Developer window gets displayed. Now you open the screen.  You will see all the five database tabs in the New / Select Database Connection with default connection to the Oracle 10G XE on the local machine[Screen shot not shown].
Read more
  • 0
  • 0
  • 3893
article-image-type-subtype-and-category-patterns-logical-data-modeling
Packt
24 Oct 2009
4 min read
Save for later

Type, Subtype, and Category Patterns in Logical Data Modeling

Packt
24 Oct 2009
4 min read
Before I cover the three logical data modeling patterns, let's review briefly how we typically model a type. Let's say you're in a car business. You can model a car as a Car entity shown in the figure below; its sample data values are in following table (I just use six numbers for the VIN, instead of the 17 characters VIN standard, in the sample). VIN (Vehicle Identification Number), the car serial number, is the unique key of the Car entity. The other attributes (Brand, Model, Year, and Manufacturer's Suggested Retail Price) can be thought as the type of a specific car  with a unique VIN. So, the type is in the entity itself. Note that you can have more than one car—each with a unique VIN—that have the same type, such as the first three Honda Accord in the sample table. If you have many cars of the same type, or, you have many car types and they're dynamic (have changes:  new, update, delete; for example, the update on the MSRP), you can easily recognize that this model is then not suitable—type model is a better solution.   VIN Brand Model Year MSRP 123987 Honda Accord 2007 20,000 456321 Honda Accord 2007 20,000 555666 Honda Accord 2007 20,000 678345 Toyota Corolla 2008 21,000   ...   ...   Type The ER (Entity Relationship) diagram of the following figure shows Car Type and Car entities and their relationship. Car Type defines each type of your cars—a type is a definition of something. The Car is the individual car, each with a serial number (Vehicle Identifier Number) that has a specific type defined in the Car Type. You can think of a Car Type entity as a template used (instantiated) by an individual car. Now you can have as many car types as you need, and type changes don't affect the cars. Table two tables after the figure contain sample data values of the Car Type—Car data model. Note that a car can belong to one car type only. On the other hand, a car type can be the type of many cars.   Car Type Key Brand Model Year MSRP 1 Honda Accord 2007 20,000 2 Toyota Corolla 2008 21,000 ... ... ... ... ...       VIN Car Type Key Owner 123987 1 Djoni Darmawikarta 456321 1 Kevin Peter 555666 1 Rao Ganipineni 678345 2 Sherman Chang ... ... ... How do we deal with product that doesn't have an individual identifier? Can we apply the same data modeling structure to, for example, commercial books? You certainly have inventory; each Inventory is an instance of the Book Type. The following figure shows the Book Type—Book data model and its sample data values, respectively. You can also apply the same data model to intangible thing, such as Service; an individual service may be identified by, for example, a contract number. The following figure  and the last table in the article show the Service Type—Service data model and its sample data values, respectively. Subtype What if you have cars that have different sets of attributes, meaning different types? You can model the different types as subtypes. The following figure shows two subtypes of the Car Type entity: Passenger Car Type and Truck Type. The Car supertype has the common attributes of its subtypes while each of the subtypes has its different attributes. Category While Type is a definition of something, Category is a way to categorize something. While Service can be of only one type, it can be of more than one category—its relationship to Category entity is many-to-many. An example of category for Service is shown in the following figure and its sample data values in the table after it. Note that you need to resolve the many-to-many relationship at implementation time   Service Category Key Service Category 1 Bundled 2 Outsourced 3 Onsite 4 Software 5 Hardware ... ... Summary Type, Subtype, and Category are similar patterns for data modeling. This article introduces these three patterns and shows their differences. One or more of them exist in most data model. If your initial data model doesn't have any one of them then you should re-inspect the data model.
Read more
  • 0
  • 0
  • 8479

article-image-data-profiling-ibm-information-analyzer
Packt
24 Oct 2009
3 min read
Save for later

Data Profiling with IBM Information Analyzer

Packt
24 Oct 2009
3 min read
Information Analyzer is a client-server software. A data profiling user (metadata analyst) works on its GUI client, so to make it easier to show you how I solve the problem I’ll use a lot of screenshots. Our example data is an Oracle table that has two columns and three rows (In real life, they can typically be more than 50 and a few millions, respectively). When you start the Information Analyzer client, called Information Server Console, you’ll be shown its start-up screen; and then, its log-in window. When your log-in is successful, the console main window will show up. Assuming the Oracle table that we’d like to profile is new; we must identify it to the Analyzer, which technically means importing its metadata. Make sure you have connected the Oracle database to the Information Analyzer server before you import the metadata of its tables. Expand Metadata Management from the HOME drop-down menu. Then, click Import Metadata. Our example Oracle data (table) is in the CLROPER database (hosted in DDOM02), so select CLROPER and then click Identify Next Level. It might take a while, particularly for a database that has many tables and many columns; so just wait. On the completion message screen, click OK to close the screen. All tables in CLROPER database will be identified (listed) including our example table named SPACE1. We’ll next identify the columns of our SPACE1 table; so select SPACE1 and then click Identify Next Level. The result shows that Analyzer has correctly identified the two columns of the table. Now, import metadata of all columns of the table by selecting the table and then clicking Import. Click OK to continue. Wait for completion. Click OK on the successful completion screen. We’re now done with the metadata of the data; we’re now ready to start our profiling task. In Information Analyzer (as in most other software of these days) we group our profiling works into projects. Here, I just use an existing project (DJONI_TEST), so select Open Project from the drop-down arrow on the right of NO PROJECT SELECTED. You’ll be shown the list of existing projects. Select your project, and click Open. Our previous (existing) profiling works are shown. Next, open click Project Properties from the OVERVIEW drop-down menu. Go to the Data Sources tab. Our SPACE1 table is not in the list yet, as we haven’t identified it specifically in our project (we did in the previous steps at the server-wide level); so we need to add it into our project, click Add. Expand the SPACE1 table to see its columns. Select all of the columns as we want to profile all of them, and then click OK. When completed, click Save All, and then close the Project Properties window. Now, we’re ready to profile our SPACE1 data, to analyze its columns. On the main toolbar select Investigate | Column analysis.
Read more
  • 0
  • 0
  • 4559
Modal Close icon
Modal Close icon