Techie: Sabarinathan Arthanari

Let's make a better world

I would like to share the interesting scenario faced with the junior system administrator(hardware guy). I hope that will help us to deal with similar characters in future. Here comes the true story.

 

Story : Eighth wonder

Part 1

Once up on a time[;)] I asked a system administrator in my office to connect the front panel headphone jack to motherboard. The guy tried to connect the cables even without switching off the system (the practice normally damages motherboard severely due to static electricity). Without checking whether actually jack was working or not he told me that the task had been completed. I tested the jack myself and found my front panel jack still wasn’t working and asked him to fix it.

t_pc642 i'm multi talentedFirst troubleshooting question he asked me was “Have you connected headphone to Red jack (mic) or green jack (speaker) ?”. As I was stunned (he knew that I had experience in IT) by the brilliant question, I replied him “green”.

He tried to solve the problem with some other combination, but was unable to do so. so he concluded “This motherboard doesn’t support analog speaker connectors.” and informed me !

 

attitude_2I was speechless for a moment and i thought that was eighth wonder in this world “Intel manufactured a motherboard which doesn’t support front panel connectors of their own cabinet”. :)

I googled for the right combination, found the solution and fixed it. Later he started shouting that I’m acting against the company policy.

The Moral of the Story… 

Never argue with a fool, onlookers may not be able to tell the difference.  ~Author unknown, attributed to Mark Twain

 

Part 2

As I was worried with his reply, I consulted with his boss regarding his attitude. Though he worries about his junior’s bad manners, I got the interesting reply as the reason for his junior’s technical skills

He is having only 3 years(?)  of experience. He is just a kid!!

 

 

Part 3

zxs527_125 Later I found that system admin tried to close the cabinet to avoid further queries and problems. But the thing he forgot to do is to fix the cover properly and it was wide open at the front.

But at that time i followed the quote of “Mark Twain” properly ;) . In some situations perception might be a problem ?

  • Share/Bookmark

In previous post we saw techniques to create collections on the fly to simulate the multi-value columns in Oracle. In this part we use simple PL/SQL function to aggregate individual collection values in to single field separated by value Delimiter.

Following function creates multi-valued string from the Oracle collection More info

FUNCTION To_String (
  Nt_in        IN Varchar2Table,
  Delimiter_in IN VARCHAR2 DEFAULT ‘,’
  ) RETURN VARCHAR2
IS
     v_idx PLS_INTEGER;
     v_str VARCHAR2(4000 BYTE);
     v_dlm VARCHAR2(10);
  BEGIN
     v_idx := nt_in.FIRST;
     WHILE v_idx IS NOT NULL LOOP
        v_str := v_str || v_dlm || nt_in(v_idx);
        v_dlm := delimiter_in;
        v_idx := nt_in.NEXT(v_idx);
     END LOOP;
     RETURN v_str;
  END To_String;

The above function helps developer to pass values to Business layer while migrating multi-value column to Oracle.

 

The following Query will first aggregate the rows in to collection table and convert to the multi-value column

SELECT migration.to_string( CAST( COLLECT( NAME ) AS Varchar2Table ) ) FROM EMPLOYEEADDRESS

Result

image 

 

Migrating Sub-Values to Oracle

Oracle supports ORDBMS concepts from version 8i which allows users to create user defined types and include them as column datatypes(Complex type in SQL developer).

Prior to Oracle 9i, collections could only be used to represent a single dimension of information (a list of names or salaries). With Oracle 9i and support for multi-level collections, PL/SQL developers can now model multi-dimensional phenomena. More info

In addition to sub-value enhancements, Oracle 10, 11 versions provides more advanced ORDBMS features.

[to be continued in ORDBMS series of Oracle]

  • Share/Bookmark

This article intends to identify technique to convert textarea HTML control to Editable Hyperlink Listbox efficiently.

 

Logic

This solution uses pure HTML and Javascript.

Step 1: Bind TextArea “Double Click” event to Javascript OpenLink() function.
Step 2: Get Caret/Cursor position with in the text area
Step 3: Extract current line from text area.
Step 4: Check for valid URL format and if necessary fix URL
Step 5: Open New window/Tab with selected URL.

Getting Caret/Cursor position

Code for getting Caret/Cursor position is based on the Mr. Alex implementation available in http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea.

However bug fix to count 2 characters for the IE line termination(“\r\n”) is included in this code.

 

Getting Currently Selected Line

GetCurrentLine() function uses string search functions to identify the line termination characters related to cursor position with in the textarea and to extract the selected line.

 

Code

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, “”);
}

 

function OpenLink(hyperLinkID) {
    var txtHyperLink = document.getElementById(hyperLinkID);

    //Step 2: Get Caret/Cursor position with in the text area
    var CaretPosition = GetCaretPosition(txtHyperLink);

    //Step 3: Extract current line text from text area.
    var line = GetCurrentLine(txtHyperLink.value, CaretPosition);

    //Step 4: Check for valid URL format and fix URL if necessary
    if (line) {
        line = line.trim();
        if (line.length > 0) {
            if (line.indexOf(‘://’) == -1) {
                line = “
http://” + line;
            }

            //Step 5: Open New window/Tab with selected URL.
            OpenHyperLink(line);
        }
    }
}

 

function GetCaretPosition(control) {
    var CaretPos = 0;
    // IE Support
    if (document.selection) {
        control.focus();
        var Sel = document.selection.createRange();
        var Sel2 = Sel.duplicate();
        Sel2.moveToElementText(control);
        var CaretPos = 0;
        var CharactersAdded = 1;
        while (Sel2.inRange(Sel)) {
            //old GetCaretPosition always counts 1 for linetermination
            //fixed
            if (Sel2.htmlText.substr(0, 2) == “\r\n”) {
                CaretPos += 2;
                CharactersAdded = 2;
            }
            else {
                CaretPos++;
                CharactersAdded = 1;
            }                   
            Sel2.moveStart(‘character’);
        }
        CaretPos -= CharactersAdded;
    }
    // Firefox support
    else if (control.selectionStart || control.selectionStart == ’0′)
        CaretPos = control.selectionStart;

    return (CaretPos);

}

 

function GetCurrentLine(Text, Position) {
    var lineTermination = “\n”; //Mozilla opera etc
    if (document.all) { // IE
        lineTermination = “\r\n”;
    }
    var lineTerminationLength = lineTermination.length;
    var startPosition = Position;
    //always search one character position back to avoid wrong calculations
    //when cursor position is at the end of the line
    if (Position > 0)
        Position–;

    var lineStart = Text.lastIndexOf(lineTermination, Position);
    //if cursor at first line or  new line and cursor at the beginning
    if (lineStart == -1 || (lineStart <= 0 && startPosition == 0))
        lineStart = 0;
    else
        lineStart = lineStart + lineTerminationLength;

    var lineEnd = Text.indexOf(lineTermination, lineStart);
    if (lineEnd == -1)
        lineEnd = Text.length;
    return Text.substring(lineStart, lineEnd);
}

 

function OpenHyperLink(line) {
    window.open(line);
}

 

Online Sample

 

Disclaimer

  1. All data and information provided on this page is for informational purposes only. Some parts of this tutorial are taken from the specified links and references. The mentioned writings belong to their corresponding authors.

  2. The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.

  • Share/Bookmark

Oracle ORDBMS support for multivalue columns (Version 8 onwards)

Version 8.0 and higher versions of Oracle are referred to as ORDBMS (Object-Relational Database Management System). The traditional Oracle database management system is extended to include Object-Oriented Concepts and structures such as abstract data types, nested tables, varying arrays, object views and references.

MultiValue columns through Collections feature of Oracle 8

“A collection is an ordered group of elements, all of the same type. It is a general concept that encompasses lists, arrays, and other familiar datatypes. Each element has a unique subscript that determines its position in the collection.

Oracle Offers following persistent collections

· Nested tables hold an arbitrary number of elements. They use sequential numbers as subscripts. You can define equivalent SQL types, allowing nested tables to be stored in database tables and manipulated through SQL.

· Varrays (short for variable-size arrays) hold a fixed number of elements (although you can change the number of elements at runtime). They use sequential numbers as subscripts. You can define equivalent SQL types, allowing varrays to be stored in database tables. They can be stored and retrieved through SQL, but with less flexibility than nested tables.

PL/SQL provides following additional non-persistent collection (cannot be stored in database tables)

Index-by tables, also known as associative arrays, let you look up elements using arbitrary numbers and strings for subscript values. (They are similar to hash tables in other programming languages.)

Example 1: Table with collection column type

1. SQL to Create a string collection

create or replace
TYPE Varchar2Table IS TABLE OF VARCHAR2(4000 BYTE);

2. Using Collection as a column in a table

CREATE TABLE BOOK
(
ID ROWID NOT NULL
, NAME VARCHAR2(200 CHAR) NOT NULL
, CONTENTS SABARI.VARCHAR2TABLE
, CONSTRAINT BOOK_PK PRIMARY KEY
(
ID
)
ENABLE
)
NESTED TABLE CONTENTS STORE AS BOOK_CONTENTS RETURN AS VALUE;

ALTER TABLE BOOK
ADD CONSTRAINT BOOK_UK_NAME UNIQUE
(
NAME
)
ENABLE;

The above statement creates 2 table with named “BOOK” and “BOOK_CONTENTS” !

So whenever we store contents to Book table, book lines will be inserted to the “BOOK_CONTENTS” table.

Inserting rows in to collections

INSERT INTO BOOK(ID,NAME, CONTENTS) VALUES  (1 , ‘Book1′, Varchar2Table(‘line1′, ‘line2′, ‘line3′, ‘line4′));

Query table

SELECT * FROM BOOK

image

Example 2: Creating Collections on the fly

Oracle 10g has introduced an extremely useful new group function, COLLECT. This function enables us to aggregate data into a collection, retaining multiple records of data within a single row (like a nested table). One of the main benefits of this function is that it makes “string aggregation” (one of the web’s most-requested Oracle technique) very simple.

So by using this feature we can manipulate multivalue column views even from normal RDBMS columns.

Example

SELECT CAST( COLLECT( NAME ) AS Varchar2Table ) FROM BOOK

  • The statement is simple NAME is Varchar2 data type.
  • The COLLECT function collects values in different rows in to collection.
  • CAST function casts the return values to be accessible by user defined Varchar2Table data type.

[To be Continued..]

References

http://sheikyerbouti.developpez.com/collections/collections.htm

http://www.oracle-developer.net/display.php?id=306

Disclaimer

  1. All data and information provided on this page is for informational purposes only. Some parts of this tutorial are taken from the specified links and references. The mentioned writings belong to their corresponding authors.
  2. The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.

  • Share/Bookmark

Why do we need to Migrate ?

Multivalue databases have an edge over Relational databases with respect to many features and applications, but still there are some limitations of using this data model which limit its use in some cases .or relatively simple application, say for example “project reporting by state and fiscal”, hierarchical representation happens to be convenient; no consideration is given to other applications, which it likely complicates.  Multivalue was not “first considered in the original theories and mathematics surrounding relational database rules.”

Data Integrity

The relational model was invented explicitly to replace hierarchical technology, of which Multivalue is one version, the latter having nothing to do with mathematics. Moreover there is no reference to integrity constraints. The focus is only on some certain types of applications, and integrity of the data is still a question., the flexibility which it provides means that integrity control generally has to be done at the application level rather than the DBMS level.

Physical Concept Vs Logical Concept

The Multivalue approach has been around forever and Mr. Codd declared it to be in violation of relational principles years ago. It is neither new, nor a replacement of Relational Model, nor a solution to anything. And if the “solution” is physical, then it has nothing to do with the data model, or repeating groups. Normalization is purely a logical concept, so it has nothing to do anything at physical, repeating groups are logical too and a violation of relational principles. It is technology that does not replace relational – it is a formal model that sits between the logical R level and the physical level, based on theory.

There is no such thing as “naturally occurring repeating groups”—it’s a matter of representation and we can choose to represent it with repeating groups, or relationally, without. The former was tried and failed, the latter has not yet been tried properly but even so, it’s much better.

So If an application requires large amount of arithmetic and real time database calculations or application model requires data integrity to be maintained in database layer, RDBMS model is more preferred.

Representing Multi-value columns in RDBMS Data model

We can use First Normal Form to normalize the multi value columns. For example in our example (as mentioned in part 1) we can use the multiplicity notation in UML to show that a contact may have more than one hobby:

hobbies-uml2

As you should expect by now, we can’t represent the multivalued attribute directly in the Contacts relation scheme. Instead, we will remove the old hobbies attribute and create a new scheme, very similar to the one that we created for the phone numbers.

hobbies-scheme

• The relationship between Contacts and Hobbies is one-to-many, so we create the usual pk-fk pair. The new scheme has only one descriptive attribute, the hobby name. To uniquely identify each row of the table, we need to know both which contact this hobby belongs to and which hobby it is—so both attributes form the pk of the scheme.

[To be Continued..]

References

www.csjournals.com/IJITKM/PDF1-2/28_Meghna_Ruchi.pdf

http://www.tomjewett.com/dbdesign/dbdesign.php?page=hobbies.php

Disclaimer

  1. All data and information provided on this page is for informational purposes only. The writings belong to their corresponding authors as mentioned in links and references. The information in this weblog is provided “AS IS” and confers no rights.
  2. The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.

  • Share/Bookmark

What’s OpenInsight ?

OpenInsight is a repository-based applications development environment that enables development teams to work collaboratively to design, develop, deploy and scale high-performance business solutions on leading messaging and client/server platforms. OpenInsight is a Windows-based application development environment that can reside on either Windows or Linux servers when used in conjuction with our network product Universal Driver 4.5. Arev32, Character to OpenInsight (CTO), the U2 Connector, WebOI and the Bravo Dashboard are all included in OpenInsight 9.0 Server Edition and above.

The basic difference between the OpenInsight and Oracle is OpenInsight supports multi-value tables natively, while Oracle supports RDBMS model.


OpenInsight is delivered with the option of using its own native table format. OpenInsight’s unique table format is fully compatible with variable length MultiValue data management products. The OpenInsight native table environment is a dictionary-driven text-oriented database that delivers the ultimate in flexibility for prototyping, designing and even deploying applications.

More Info

What’s Multi-Value Database ?

MultiValue Databases are a type of multidimensional database, typically considered synonymous with PICK, a database originally developed as the Pick operating system.

An efficient and flexible database technology designed to work in a virtual machine, but one that predates relational (SQL) databases. Current terminology includes multidimensional and post relational.

MultiValue databases differ from traditional relational database in that they have features that support and encourage the use of attributes having a list of values, rather than all attributes having a single value. They are often categorized with MUMPS within the category of post-relational databases, although the data model actually pre-dates the relational model.  More Info

Example

Contact hobbies
contactid firstname lastname hobbies
1639 George Barnes reading
5629 Susan Noble hiking, movies
3388 Erwin Star hockey, skiing
5772 Alice Buck
1911 Frank Borders photography, travel, art
4848 Hanna Diedrich gourmet cooking

In this case, there are many distinct values entered for it in the same column of the table. This is called a multivalued attribute.

How is it different from RDBMS ?

The primary difference between the Multi-value database and RDBMS is treatment of multivalue columns.

The data stored in a field may be made up of multiple values. By adopting this data model instead of using additional columns, the data model imposes no limit to the number of items that may be included in an order. In a Multivalue database, the tables can gain a fourth dimension (sub values). Multivalue queries are also somewhat shorter, easier to understand and more efficient in resources to process.

Multivalue record structure favors a “denormalized” decomposition, where all of the data for an entity is stored in a single record, obviating the need to perform joins. When managing large, sparse data sets in this way can result in efficient use of storage space.

In one of the tests simulating a data analysis application typical for a telecommunications software firm, Cache (supporting Multivalue database) was 41% faster than Oracle 9i (supporting relational database) when creating a data mart of mobile phone information. When the resulting data mart was queried using SQL, Cache’s response times ranged from 1.8 to 513 times faster. Clearly, Multivalue unique multidimensional data engine make it a good choice for applications that require rapid analysis of large amounts of data. More info

Compared to relational (SQL) databases… … MultiValue (MV) has:

  • For each database table (file in MV):
    Each field (attribute in MV) within a record/row (item in MV) can have repeating data elements (values in MV) and each value can have multiple sub-values – for relational databases each field is fixed to one value.
  • Each attribute, value and sub-value is dynamic in length – for relational databases each field has a fixed length.
  • A more “natural language like” and efficient built-in enquiry and reporting tool…
    … refer to the MV Query example below for comparison with a relational database.
  • Inbuilt database environment features that typically mean little to no ongoing maintenance – for relational databases they have always needed dedicated Database Administrators (DBAs). More Info
Multi-Value Database structure
  • MultiValue is a technology that understands three dimensional data directly. Most applications that use MultiValue technology understand three-dimensional data structures refer to them as Fields, Values, and Subvalues.
  • A field, or column, is the same as it would be in a normalized database.
  • A Value is a further breakdown of a column. For example, in a normalized database there might be columns defined for Address1, Address2, Address3. In a MultiValue database there would be a definition for a column named Address, and stored in that column would be either one, two, three, or more values. These different values would be delimited by a special character known as a Value Mark.
  • A Subvalue is a further breakdown of a value. For example, if there is a column defined for Phone, and there is a value called Home, there may be two sub values for the home phone number- perhaps the main number and a home office phone number.
  • Another distinct advantage to the MultiValue world is that the tables are extremely flexible. Columns can usually just be added to the database definition and used immediately. There is no need to shut down the database , lock out the users, add the column, and rebuild the database. A new column is simply added to a dictionary and that column is then immediately available.
  • MultiValue databases also have calculated columns. These columns, which actually contain small programs that are run when the fields contents are needed, allow real-time calculation of values. For example, in a MultiValue database a person’s age wouldn’t be stored, the person’s birth date would be stored. There would be a column named AGE, but it would be a calculated column. The calculation in the column would take the current date, subtract from it the person’s date of birth, and then display the age.
    More Info

[To be Continued..]

References

http://www.revelation.com/revelation.nsf/1f484fef89cd63e1852569c900787d0e/be0c2876a6f1056b85256dc500587dd5?OpenDocument#OINT

http://www.intl-spectrum.com/MultiValueSymbol/Default.aspx

http://www.intl-spectrum.com/database/12/OpenInsight.aspx

http://www.multivalue.net/

http://www.northgate-reality.com/about_us.php?pageId=85

http://www.csjournals.com/IJITKM/PDF1-2/28_Meghna_Ruchi.pdf

http://www.tomjewett.com/dbdesign/dbdesign.php?page=hobbies.php

Disclaimer

  1. All data and information provided on this page is for informational purposes only. The writings belong to their corresponding authors as mentioned in links and references. The information in this weblog is provided “AS IS” and confers no rights.
  2. The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.


  • Share/Bookmark

This article intends to give brief introduction notes to start with Silverlight based development. I would like to give list of citations to the valuable resources available for Silverlight.

 

What is Silverlight ?

Silverlight is the RIA application framework from Microsoft which is competitive product for the Adobe Flash. more info

Developers can use their existing knowledge of .Net languages like C#, VB to develop client side functionality. Silverlight includes a cross-platform, cross-browser version of the .NET Framework, and enables a rich .NET development platform that runs in the browser.  Developers can write Silverlight applications using any .NET language (including VB, C#, JavaScript, IronPython and IronRuby).

 

Why RIA ?

To provide more interactive user interfaces like desktop application that run cross platform and cross browser. As we know multimedia, media streaming, animations, and blend vector graphics are normal capabilities of RIA frameworks.  more info

 

How it works ?

CoreCLR: Silverlight includes a cross platform version of the .NET Framework and its size (CLR + a WPF and .NET FX library API subset + dynamic language support) is ~4MB. Silverlight does not require the .NET Framework to be installed on a computer in order to run.

It delivers the same type-system, garbage collector, and JIT code generation engine. The CoreCLR term refers to the CLR that powers the Silverlight. It’s refactored, modularized, tightened, simpler with fewer dependencies. Silverlight includes a subset of the full .NET Framework class library which provides support for collections, generics, IO, threading, globalization, networking, and LINQ.

Silverlight can use the standard ASP.NET application services (membership, roles, profile, etc), and can call either WCF or ASMX web-services hosted within ASP.NET.

HanselmanDotNetEcosystemVisualizationV02_thumb[4]

Important Concepts

WPF UI Framework: Silverlight 2 includes a rich WPF-based UI framework that makes building rich Web applications much easier. Silverlight supports simple & extended controls similar to WPF controls for example Grid, TreeView, Right Click etc

HTML DOM API: IT provides a managed HTML DOM API that enables you to program the HTML of a browser using any .NET language. Silverlight includes a JSON serializer that supports automatic marshalling of .NET datatypes to/from Javascript. For example Javascript code can call a C# method within Silverlight, and have the C# method return a .NET collection which is then serialized by Silverlight into a Javascript collection

Rich Networking Support: Silverlight includes rich networking support.  It includes out of the box support for calling REST, WS*/SOAP, POX, RSS, and standard HTTP services

Local Storage: Isolated Storage gives your Silverlight application access to storage resources on the client. It’s “isolated” because the store is partitioned per application, meaning no other applications can access files in your storage. On the other hand, your application (application defined by its URL) always gets the same storage, even if it’s run in a different browser.

Databinding: Silverlight now supports two-way, one-way, and one-time databinding between visible controls and classes in code that represent application logic. One-way and one-time databinding are for read-only controls. Two way databinding lets the user make changes that automatically update classes in the model.

 

Design Pattern

Silverlight is developed with MVVM Model-View-ViewModel pattern more info. View and ViewModel primarily works in Client side while Model (3 Tier architecture) works in Server side.

mvvm-thumb Layers

viewmodel 

More info:

http://nirajrules.wordpress.com/2009/07/18/mvc-vs-mvp-vs-mvvm/

History Roadmap

Silverlight 1.1 http://weblogs.asp.net/scottgu/archive/2007/05/07/silverlight.aspx

Silverlight 2.0 http://weblogs.asp.net/scottgu/archive/2008/02/22/first-look-at-silverlight-2.aspx

Silverlight 3.0 http://timheuer.com/blog/archive/2009/03/18/silverlight-3-whats-new-a-guide.aspx#tools

Silverlight 4.0 http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx

Silverlight feature suggestion

 

Future trend

DLR (dynamic language runtime)

The above core CLR has been developed to DLR though which capabilities were under estimated initially according Mr. Scott. http://www.hanselman.com/blog/PuttingMixSilverlightTheCoreCLRAndTheDLRIntoContext.aspx

Developers can write .NET code using any development language (VB, C#, Javascript, Python, Ruby and more) in the web-browser using DLR. (see below). Compiled/JIT’ed JavaScript is at least 1000x faster than interpreted. Supports Windows and Mac OS X

Now Framework 4.0 provides DLR support natively

runtime

More info:

http://msdn.microsoft.com/en-us/library/ms171868.aspx

http://www.codeproject.com/KB/dotnet/DOTNETre4pt0.aspx

http://www.developer.com/print.php/3849871

 

HTML 5

HTML5, a groundbreaking upgrade to the prominent Web presentation specification, could become a game-changer in Web application development, one that might even make obsolete such plug-in-based rich Internet application (RIA) technologies as Adobe Flash, Microsoft Silverlight, and Sun JavaFX.

More info HTML5: Could it kill Flash and Silverlight?

 

 Tools

  • Expression Studio - Design, asset management and interaction design application suite with XAML editing and Visual Studio integration, along with a Media Encoder.
  • Silverlight Streaming – More developer focused than YouTube, this service gives you 4GB of free storage and virtually unlimited streaming of video clips using Microsoft’s content deployment network.
  •  

    References

    http://weblogs.asp.net/scottgu/archive/2007/05/07/silverlight.aspx

    http://www.hanselman.com/blog/PuttingMixSilverlightTheCoreCLRAndTheDLRIntoContext.aspx

    http://en.wikipedia.org/wiki/Model_View_ViewModel

     

    Disclaimer

    1. All data and information provided on this page is for informational purposes only. The writings belong to their corresponding authors as mentioned in links and references. The information in this weblog is provided “AS IS” and confers no rights.
    2. The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.

    • Share/Bookmark

    Technorati

    No comments

    • Share/Bookmark
    Powered by WordPress Web Design by SRS Solutions © 2010 Techie: Sabarinathan Arthanari Design by SRS Solutions