Tuesday Sep 22, 2009

Videos to get acquainted with Apache Derby and Java DB

javadb.png

derbyLogo.png

Kristian Wagaan and Richard Hillegas, both Apache Derby committers who also work on Java DB, recently gave some great presentations about Apache Derby and Java DB.

Kristian Wagaan presented at the 2009 OpenSQLCamp, in conjunction with FrOSCon 2009 in Europe.

The presentation (slides) gives a brief overview of Apache Derby, its history and the community around it. Further, it goes into the details of features that have been added in the latest releases and show how they enable powerful ways to use a relational database.




Rick Hillegas gave an introduction of Java DB / Apache Derby at The San Francisco Java User Group's Sep 8th event in San Francisco.


Monday Sep 14, 2009

Java DB 10.5.3 is now available

Following the release of Apache Derby 10.5.3, Java DB which is Sun's supported version of this last one is also now available.

Java DB 10.5.3 is primarily a bug-fix release and inherits all the bug fixes and localized messages from Apache Derby 10.5.3.

Java DB offers installers for the following platforms:

  • Solaris
  • Linux
  • Windows
  • Mac OS X (newly added)

Here is a recap of all changes that are coming as part of Java DB 10.5.3:
  • SQL Roles - SQL roles (as described in SQL 2003 and errata) are useful for administering privileges for groups of users. Administering roles is generally less error-prone than administering privileges for individual users. SQL Roles are defined in Feature T331 "Basic roles" and Feature T332 "Extended roles". Java DB 10.5 implements a subset of T331, plus support for CURRENT_ROLE, which is a part of T332.

  • Generated Columns - Generated Columns is a feature which instructs Java DB to fill a column with an expression built out of other columns in the row. Java DB constructs these column values at INSERT and UPDATE time. The user declares indexes on these columns. This in turn improves SELECT performance since it lets users declare indexes on pre-computed pieces of the WHERE clause. This feature satisfies support for SQL Feature T175.

  • LOB Improvements - There were many performance and usability improvements for BLOBs and CLOBs.

  • Replication of encrypted databases - With 10.5 it is possible to replicate encrypted databases.

  • OFFSET/FETCH FIRST - SQL 2008 has added new syntax to support a direct way to limit the returned set of rows in a result set, through the fetch first and offset clauses.

  • In-memory back end - Initial implementation of a storage engine for Java DB where all data is kept in memory. There is no documentation for this feature. This functionality itself is not yet fully implemented, but users are welcome to experiment with it. For details, see the Primer for In-memory Back Ends.

  • Standard ALTER COLUMN syntax - Allow standard SQL "SET" keyword in ALTER COLUMN syntax, like so: "ALTER TABLE ALTER COLUMN columnname SET DEFAULT default-value"

  • SYSCS_UTIL.SYSCS_UPDATE_STATISTICS - New system procedure that updates cardinality statistics (or creates them if they do not exist) for a table's index or for all the indexes on a table, allowing a user to ensure that a query plan based on the most recent state of the table can be created.

  • Service tag - Introduction of the Java DB registration service (service tag).

Further details on new features, changes, and issues in this release can be found in the Release Notes.

Wednesday Aug 26, 2009

Apache Derby 10.5.3 Bug-Fix Release is now available!


The Apache Derby project is pleased to announce a new bug-fix release of Derby, 10.5.3.0.

Apache Derby is a subproject of the Apache DB project. Derby is a pure Java relational database engine which conforms to the ISO/ANSI SQL and JDBC standards. Derby aims to be easy for developers and customers to use.

Derby 10.5.3.0 can be obtained from the Apache download site:
http://db.apache.org/derby/derby_downloads.html

Derby 10.5.3.0 contains many bug fixes plus localizations for messages added in the previous feature release, 10.5.1.1.

10.5.3.0 replaces 10.5.2.0, which introduced a query-ordering regression.

Here is the list of bug fixes addressed in 10.5.3.

Friday May 29, 2009

Java DB at CommunityOne and JavaOne 2009

 

The Java DB team will be at CommunityOne and JavaOne 2009 next week.

Feel free to come and visit us at the Java DB POD and share feedback with us. You might even get a nice T-Shirt ;-)

We will show demo's of new features, including some nice JavaFX application using Java DB / Apache Derby.

Java DB 10.5.1 now available

The Java DB project is pleased to announce a new feature release of Java DB 10.5.1.

Java DB is Sun's branded distribution of the Apache Derby open source  database. Java DB is a pure Java relational database engine which conforms to the ISO/ANSI SQL and JDBC standards. Java DB aims to be easy for developers and end-users to work with.

Java DB 10.5.1 can be obtained from the Java DB download site:
http://developers.sun.com/javadb/downloads/index.jsp

Java DB 10.5.1 introduces the following new features and improvements:

  • In-memory databases for test rigs and transient data
  • Replication of Encrypted Data for failover of sensitive databases
  • OFFSET/FETCH FIRST for paging through query results efficiently
  • SQL Roles for administering fine-grained access controls
  • Generated Columns for speeding up queries by pre-computing results
  • LOB Improvements for speeding up access to large binary and text objects
  • Optimizer Statistics Improvements for better management of query plans

Java DB offers the following: 

  • Installers for various platforms
  • Support offering (more info)
  • Notification of new releases and updates via registration
  • Native Netbeans integration
  • Bundled in GlassFish and Sun JDK6
If you are interested in learning more or/and sharing feedback about Java DB, please come and visit us at our POD during CommunityOne and JavaOne 2009.

Friday May 01, 2009

Apache Derby 10.5.1.1 Feature Release is now available!

The Apache Derby project is pleased to announce a new GA feature release
of Derby, 10.5.1.1.

Apache Derby is a sub-project of the Apache DB project. Derby is a pure
Java relational database engine which conforms to the ISO/ANSI SQL and
JDBC standards. Derby aims to be easy for developers and end-users to
work with.

Derby 10.5.1.1 can be obtained from the Derby download site:
http://db.apache.org/derby/derby_downloads.html.

It contains the following new features:
  • SQL Roles - SQL roles (as described in SQL 2003 and errata) are useful for administering privileges for groups of users. Administering roles is generally less error-prone than administering privileges for individual users. SQL Roles are defined in Feature T331 "Basic roles" and Feature T332 "Extended roles". Derby 10.5 implements a subset of T331, plus support for CURRENT_ROLE, which is a part of T332.
  • Generated Columns - Generated Columns is a feature which instructs Derby to fill a column with an expression built out of other columns in the row. Derby constructs these column values at INSERT and UPDATE time. The user declares indexes on these columns. This in turn improves SELECT performance since it lets users declare indexes on pre-computed pieces of the WHERE clause. This feature satisfies support for SQL Feature T175.
  • LOB Improvements - There were many performance and usability improvements for BLOBs and CLOBs.
  • Replication of encrypted databases - With 10.5 it is possible to replicate encrypted databases.
  • OFFSET/FETCH FIRST - SQL 2008 has added new syntax to support a direct way to limit the returned set of rows in a result set, through the fetch first and offset clauses.
  • In-Memory back end - Initial implementation of a storage engine for Derby where all data is kept in memory. There is no documentation for this feature. This functionality itself is not yet fully implemented, but users are welcome to experiment with it. For details, see the Primer for In-memory Back Ends.
  • Standard ALTER COLUMN syntax - Allow standard SQL "SET" keyword in ALTER COLUMN syntax, like so: "ALTER TABLE ALTER COLUMN columnname SET DEFAULT default-value"
  • SYSCS_UTIL.SYSCS_UPDATE_STATISTICS - New system procedure that updates cardinality statistics (or creates them if they do not exist) for a table's index or for all the indexes on a table, allowing a user to ensure that a query plan based on the most recent state of the table can be created.

In addition, Derby 10.5.1.1 contains many bug and documentation fixes.

Java DB, which is Sun's distribution of Apache Derby should be available as a 10.5.1.1 release level very soon.

Friday Mar 27, 2009

Java DB Articles and Interviews with Masood Mortazavi, Engineering Manager

Amongst the recent updates to Java DB's portal, I recommend reading these 2 great interviews of Masood Mortazavi, engineering manager for Java DB.

You can also find a various selection of technical articles, tips and white-papers.

If you are using Netbeans, this article will show you how to use Java DB more effectively inside this IDE. 

Wednesday Mar 04, 2009

JavaFX and Java DB / Apache Derby Demo Applications

Sergey Surikov has updated and enhanced his CrudFX application to work with JavaFX 1.0.

These new applications below are using Java DB / Apache Derby's bundled demo database 'ToursDB' which contains travel agency sample data...

The first one has more advanced UI and graphic elements. Click on the screenshots below for more info.

Tuesday Dec 16, 2008

Java DB on Twitter - Become a follower

Java DB (based on Apache Derby) is now on Twitter. If you want to follow the latest about Java DB, then become a follower ;-)

Wednesday Oct 22, 2008

Java DB / Apache Derby Table Functions White Paper

Rick Hillegas has posted a great white paper on Java DB / Apache Derby support of ANSI SQL 2003 Table Functions.

A table function is like a virtual table that allows you to access data externally as if it was a local table, via the full, expressive power of SQL.

Data returned by these special functions can come from anywhere:

  1. files - files and web resources
  2. collections - in-memory collections
  3. foreign data - other databases, including non-relational sources
  4. streams - transient information streams, including data feeds and device outputs

Table functions are easy to implement and Rick's white-paper has several examples of practical table function use cases.

Derby has itself several implementations of virtual tables that can be accessed directly. One that you might already know is LOCK_TABLE that shows all locks currently held in the database.
TRANSACTION_TABLE, STATEMENT_CACHE and SPACE_TABLE amongst others are additional ones that can be quite useful.

Documentation about Java DB / Derby table functions can also be found here.

Monday Aug 11, 2008

Apache Derby Case Study: Benefits of a Microkernel architecture

Software embracing a microkernel architecture has been happening for the last 20 years, yet the great aspects of this particular architecture are too often undermined and not considered when working on a new project. There are various reasons for this, history behind it with poor experiences, but there has also been a lot of lessons learned . So what can one benefit from a microkernel architecture?

Microkernel introduction

In the last two decades, a lot of changes happened in the world of software and Internet has revolutionized quite a few trends. Microkernel architecture used to be adopted for operating system type of implementations pretty much exclusively. I remember about ChorusOS, a Unix variant and first-generation microkernel OS developed in the early 90's which was targeted at high-availability applications in the telecommunications space. Chorus was truly innovative back then and like Mach, another first generation microkernel OS implementation, suffered performance issues due to message processing between the kernel and user spaces (no sharing of address spaces). Minix, another well-known unix-like OS based on a microkernel architecture was created by Andrew S. Tanenbaum in 1987 and influenced the development of Linux although Linus Torvalds went with a monolithic kernel architecture instead.

There has been quite a few debates regarding the benefits and tradeoffs of a microkernel architecture versus a monolithic one. Most Unix operating systems are based on the last one, with no messaging between parts of the system and an easier (and controlled) access between the kernel and user spaces. A microkernel-based implementation typically grants the software with added modularity and flexibility due to the abstraction and extra independency (clear boundaries) between the various modules / parts of a system.

I stated earlier that trends had changed in the last 20 years and although it may sound like stating the obvious, what I really meant to say is that software architectures do evolve due to other factors such as hardware, markets and  new requirements. Today one can see a lot more software implementations based on a microkernel architecture, due to an increase demand and new requirements motivating that choice. Hardware (e.g. memory, CPU) has gotten a lot faster and cheaper, there is a lot of hardware environments to port to, the internet and its fast moving pace has increased the demand for more dynamic and flexible software.

Multi-threaded server applications are a lot more popular these days and the overhead of a microkernel-based implementation is no longer an issue when it comes to interactions between various modules involved in a particular processing operation. It used to be true for the most part, when IPC mechanisms had to be used to relay messages between modules running as part of different processes.

Why Microkernel

A microkernel architecture could be summarized to a "highly modular collection of application-neutral abstractions upon which can be built robust, flexible and dynamic applications" and brings the following and non-exclusive benefits to software implementations:

  • Modularity
  • Flexibility
  • Extensibility
  • Better footprint management
  • Easier development, unit testing, maintenance and portability

The modularity, flexibility and extensibility aspects are what I would consider the most important ones of a microkernel-based implementation. A highly modular architecture  allows protocols to be separated from their implementations as well as maintaining a level of independence between the various modules and components / services (enforcement of boundaries) of the system. Flexibility grants you with dynamic loading and unloading of modules and extensibility gives the developers means to extend the current system with new protocol or schemes implementations.

Footprint management can be an important issue in certain environments and the ability to remove unnecessary components as part of your application can help reducing the footprint significantly.

Modules can be developed and unit tested independently of each others and portability is usually easier to handle as non portable logic can be placed at the kernel level directly and not mixed with non-kernel components.

As far as potential performance improvements, I think this is very debatable unless one is dealing with a single-threaded monolithic implementation and in this case it would be slower on SMP machines obviously. I'm a big fan of multi-threaded implementations versus multi-process ones and in this case both architectures would run better on multi-core systems.

Microkernel-based architecture has also reached the world of database systems and most recently, Drizzle, a fork of the MySQL core engine has been announced and is supposedly aimed at Web and Cloud applications. This confirms the need for more modular and flexible implementations at the database management system level.

Microkernels and the likes in Java land

The Java platform and more specifically the language, facilitates the development of microkernel-based implementations. The object-oriented aspect of Java allows abstractions via published interfaces to be defined for the various parts to be implemented. In other words, this enables a clear separation between the protocol various implementations. Java dynamic class loading also allows modules to be loaded on the fly as needed.

To name a few Java applications and frameworks which have adopted a microkernel-based architecture:

  • GlassFish V3 has adopted HK2, the Hundred Kilobytes Kernel, with a module subsystem and component model on top of OSGI
    https://hk2.dev.java.net/

For an example of a Spring DM application leveraging OSGI dynamic module system and separation of application logic into modules, I recommend reading this article.
Apache Derby which can also run as an OSGI bundle (since 2005) is used in this example as well.

There is also growing interest in the cloud computing arena with having a more modular, flexible and extensible Apache Hadoop. Being able to plug-in a query language of choice on top of Hadoop's huge datasets is a very attractive value-proposition indeed.

Apache Derby Case Study: How to benefit from a Microkernel architecture

Apache Derby / Java DB has been supporting a highly modular architecture since its inception in 1997 with its first release as part of Cloudscape. Derby's system is composed of a monitor, acting as a kernel of its own, booting and shutting down services as well as discovering appropriate modules to load for a particular service. As an example, different modules can be loaded during boot-up based on the environment such as the JVM version. Modules themselves can also require other modules to be loaded in the environment.

Derby already supports pluggable authentication schemes as well as pluggable raw storages via its module-based subsystem. It promotes a clean separation between the SQL and Store layers which favors the implementation and pluggability of different types of storages. For instance, one could envision a GRAPH storage for Derby to enable a graph-based data model to be accessed via Derby's relational engine. There is already some implementation of an in-memory storage and even a store-less storage type to test Derby's layers separation and submit queries against non-database objects.

The extra benefit of having a clear separation between a protocol and its implementation allows other projects to re-use parts of the system and contribute back to the open source community. For instance, several project have expressed their interest in integrating Derby's raw B-Tree storage as it has proven to be robust over 10 years and has an active open source community.

There are already on-going efforts and proposals to make Derby more flexible and reduce dependencies between modules of the store layer and have a cleaner pluggable storage implementation. When this modular architecture got implemented 10 years ago, there was little demand for specialized and pluggable storage. This has changed with new types of data models and requirements for web applications and cloud computing, translating into innovations at the data management level.

The good news for Derby is that it has already gotten the proper foundations in place to go the extra mile and have a clean microkernel architecture. This would not only benefit the store layer but also other parts of the engine, such as the SQL compiler (parsing and execution plan generation) and the access layer, residing above the store. For instance, one could imagine having Derby's SQL layer plugged-in on top of Hadoop, as an extension to be able to run SQL queries against MapReduce datasets.

In Conclusion

Software implementations which are supporting a microkernel architecture inherit highly modular and flexible characteristics. The performance gap between a monolithic and microkernel architecture is no longer much of an issue, especially in a multi-threaded environment where messaging is done via local interfaces without requiring the use of IPC mechanisms.

The dynamic nature of web applications and requirements to constantly adapt to new standards and protocols will continue to promote this architecture. OSGI has already showed some path and additional web frameworks have become compliant.

Derby with its highly-modular architecture excels in an embedded server mode configuration and is a natural database storage of choice for the Java platform and microkernel-based implementations in the middle-tier.

Wednesday Jul 30, 2008

SNCF rides on GlassFish and Java DB


As Alexis Moussine-Pouchkine posted on this blog, the French railways company, SNCF uses GlassFish and Java DB (based on Apache Derby) to power a monitoring application which produces alerts with a real-time graphical representation of key system variables as well as PDF reports.

Don't miss this questionnaire with Franck Leprêtre, Software Architect at SNCF.

Java DB version 10.2.2.0 is bundled in Glassfish V2.

Monday Apr 28, 2008

Java DB & Apache Derby 10.4.1 GA released

Java DB & Apache Derby 10.4.1 GA have been released.

10.4.1 introduces some significant features:

  • Asynchronous replication with manual failover allows you to maintain an up to date copy of your (master) database on a different host (the slave). In the case of a crash on the master database you can perform failover to the copy (slave database) and continue serving client requests against your database. The section titled "Replicating databases" in the Server and Administration Guide has more information.

  • Table functions let you slice, dice, and zipper together external data. Using table functions and standard SQL, you can pose sophisticated queries against in-memory collections, flat files, web resources, non-relational databases, etc. Table functions also let you efficiently import data from web feeds, sensor logs, and other relational databases. For more information, please see the section titled "Programming Derby-style table functions" in the Developer's Guide.

  • Java Management Extensions (JMX) for Java DB, allowing local and remote monitoring and management of running Java DB instances (embedded or Network Server). You can use graphical tools such as JConsole or VisualVM to access Java DB's MBeans. You can also write your own Java code to do the same, using standard JMX APIs.

Java DB 10.4.1 also brings performance boosts (better scalability on multi-core machines, network client caches), additional SQL capabilities (unique constraints on nullable columns, limit/offset) and usability improvements (bracketed comments, ij continuation markers).

For more details, please see the New Features and Release Notes references at the Java DB portal.

Monday Dec 03, 2007

JavaPolis '07 is Around the Corner




JavaPolis 2007 is starting on december 10th in Antwerp, Belgium and as expected it is already sold-out.

If you don't happen to know, JavaPolis is one of, if not, the biggest Java conference in Europe. There will be 3,200 attendees this year and some great technical content.

I'm going to be presenting the following sessions on Apache Derby / Java DB:

Throughout these sessions, the audience will get to see how Java DB can be integrated in the various web tiers and throughout various scenarios. I will cover how it can be used to empower web, standalone and server applications, as well as how it differentiates itself from traditional RDBMS, due to its unique architecture and capabilities for various types of usage.

Kristian Waagan and Jørgen Løland  from the Sun Java DB engineering team will be discussing about what's coming up in the next release of Apache Derby - Some very cool stuffs indeed.

Feel free to stop by our booth to ask questions and share your experiences; who knows, you might end-up getting some goodies, it is nearly Christmas after all ;)

See you in Antwerp!

Friday Nov 30, 2007

Using Apache Derby on Java ME platforms

As you may already know, Apache Derby supports the JDBC API defined for the Connected Device Configuration Foundation Profile, also known as JSR169. The features supported are a subset of the JDBC 3.0 specification. Support for JSR169 is limited to the embedded Derby driver.

John Embretsen has put a great page together with hints and resources about Apache Derby's support for Java ME (also known as J2ME) environments. This also applies to Java DB, which is Sun's supported version of Apache Derby.

If you need to know into which JDBC environment you're running as part of your application, you can use this tip to dertermine for instance if you're running within some JSR169 context.

Thursday Nov 15, 2007

Developing with Java DB




In this podcast, Masood Mortazavi discusses about the advantages of developing and deploying apps with Java DB.

Developing Real-Time RIA's with Comet and Apache Derby / Java DB

ApacheCon US 2007 

Jean-Francois Arcand and myself gave a presentation at ApacheCon US 2007 on how to develop real-time rich internet applications using Comet and Apache Derby / Java DB.

You can download the presentation slides here.

The chat application demo we showed, highlighted how Apache Derby can be used as a web client store service from JavaScript to rapidly handle and persist incoming messages sent via Comet to a web client.

With little coding, the web client store service can persist data locally and asynchronously, allowing web applications to perform searches for online and offline chatting and viewing.

The demo was run with the new (early access) Java SE 6 Update N (formerly known as Consumer JRE). I definitely observed improved JRE cold start-up time and the web client store service extension gets installed in a much more convivial way than ever.

It is good to see Java deployment and runtime being improved to faciliate the delivery and usage of Java-based modules onto a web client. I can envision new (Java) services being made available for people to integrate within their web applications.

 

Tuesday Oct 16, 2007

How to start JavaDB / Apache Derby as a Windows Service

In this blog, Byron Nevins shows how to enable Java DB to start as a Windows service using GlassFish's appservService facility. You can also find more information about Java DB bundling in GlassFish here.

Wednesday Sep 26, 2007

Using Java DB / Apache Derby with JRuby on Rails on GlassFish

+ 

Arun Gupta has posted some information about using Java DB / Apache Derby as part of a JRuby on Rails application on GlassFish. Java DB is bundled with GlassFish and can be used as a multi-user RDBMS, running embedded in the same JVM as GlassFish or as a standalone database server in its own host and JVM.

Monday Aug 13, 2007

Apache Derby 10.3.1.4 has been released


The Apache Derby project is pleased to announce a new feature release
of Derby, 10.3.1.4.

Notes describing the difference between Derby release 10.3.1.4 and the preceding release 10.2.2.0 are available here.

Monday Jul 09, 2007

Apache Derby 10.3 release candidate is now available


The Apache Derby community has delivered a release candidate of Derby (10.3) which can now be downloaded.

A non exhaustive list of new features in this release:

- DBA Powers to control who can shutdown, encrypt and upgrade databases.
- Secure Server which makes the Derby Network Server secure by default.
- Language Based Ordering which adds built in language based ordering (collation) and like processing to Derby.
- SSL/TLS to allow secure SSL/TLS communication between a client and a Derby server.
- Various performance improvements in query processing along with reduced CPU usage in Derby embedded core engine.
- Alter Table DROP or RENAME of a column. This means that most dynamic schema modifications are now possible in Derby.

More details at http://wiki.apache.org/db-derby/DerbyTenThreeRelease

NOTE that this is a release candidate, not a GA (General Availability) one, which should be available soon after public testing has completed and reported issues have been addressed.

Monday Jun 25, 2007

Hints, Tips and Useful Information for Apache Derby Users


Apache Derby's WIKI is full of wonders when it comes to resources. I reckon it is not obvious to navigate the WIKI and find relevant information but if you're interested and curious about some Apache Derby & Java DB hints and tips, then point your browser to this link and bookmark it ;-)

Tuesday May 22, 2007

Java DB Support


The Java DB (based on Apache Derby) support offering page is now online. Note that you can also consult the Apache Derby derby-user mailing list using Nabble for getting answers or even post your questions to this last one. Apache Derby has a very active community and getting feedback via the mailing lists is a way to participate. In fact, by asking questions on the list, one is in a way adding persistent content that someone might find useful and get to via Nabble at some point ;-)

Monday May 07, 2007

First Commercial Application to run on JRuby also uses Apache Derby

I heard the news from JRuby core developer Olivier Nutter at CommunityOne as I was setting up for my presentation with Kevin Henrikson from Zimbra.

Yes, so ThoughtWorks Studios will have their collaborative development project management solution named Mingle be the first commercially-distributed Rails application to run on JRuby.

Mingle 1.0 which should be released in June 07', will be running with a Jetty web front-end and an Apache Derby database back-end.

InfoQ blog on the subject reports that performance has not been a major concern. The current runtime easily supports hundreds of concurrent users with a simple cluster, and JRuby performance has been getting faster all the time. According to the team, experimental deployments have included 10 JRuby interpreters running in a single JVM process.

Thursday May 03, 2007

Enabling Offline Web Applications with Java DB

As David Van Couvering pointed out in his blog, I will be co-presenting with Kevin Henrikson from Zimbra at CommunityOne and JavaOne 2007 next week. Kevin will especially highlight how they have implemented offline support in their current Zimbra Desktop offering.

We will discuss how today's and tomorrow's Rich Internet Applications (RIA's) can be enabled to run offline and allow the users to keep using the same application, while not being connected to the net.

You can get a sneak peak of what we will talking about based on David Berlind's recent article on the subject of enabling offline Rich Internet Applications using some local storage such as Java DB / Apache Derby and some Local Ajax (LAJAX) or Asynchronous JavaScript technic based on LiveConnect.

About

forsini

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks