This is a
The scenario we will be using for the tutorial assumes we are developing an application for two customers named Solo and Duplex. Each customer has their own upgrade timing.
| Time | Solo | Duplex |
|---|---|---|
| t1 | install r1.0 | |
| t2 | patch to r1.1 | |
| t3 | upgrade to r2.0 | install r2.0 |
During the lifecycle of an application, the development team may produce thousands of database changes. Periodically, we will want to consolidate these changes so that a fresh install can be done rapidly (also essential for the continuous integration environment), and so that we can ship a smaller set of changes to customers for upgrading.
The chosen strategy, is to clean up the
| Script | Description | Create | Upgrade from X-1 | Apply latest changes to version |
|---|---|---|---|---|
| lb_install | Perform fresh install for version X | X | X | |
| lb_upgrade_to_major | Upgrade from (X-1) to X | X | X | |
| lb_update | Upgrade within same major version, eg 1.1 to 1.5 | X |
The directory structure we will build during this tutorial is shown below (assuming that we are delivering version 5.x). Instead of using a Subversion server, we will use a local repository in the repo
directory.
D:\projects +-- lbdemo +-- repo <-- Subversion repository +-- trunk <-- Working directory +-- install <-- Installation changelogs +-- latest <-- Changelogs for replaceable objects (packages, triggers, views) +-- v004 <-- Changelogs to upgrade from version 4.0 +-- v005 <-- Changelogs to upgrade from version 5.0
lb_install: A fresh install for version 5.0 will run:
install
latest
creating 'replaceable' objects
lb_upgrade_to_major: An upgrade from version 4.x to 5.0 will run:
v004
v005
lb_update: An update from version 5.x will run:
v005
The scenario for this tutorial is illustrated in the diagram below. It will be handy to print this diagram for reference while you are going through the tutorial. Each of the blue boxes is a Subversion revision. The contents of a box is the commit message which describes the change.
If you don't already have an Oracle database available, then download Oracle XE from the Oracle Technology Network and install it on your computer. The XE edition of the database is free to use for development and production purposes.
There are many tools available to manage your database objects. If you haven't already got such a tool, then take a look at SQL Developer. SQL Developer is available as a free download at the Oracle Technology Network.
Oracle JDeveloper is another free tool available from the Oracle Technology Network. It has too many features to list here, we will only mention the XML editor. This editor is schema aware, and makes it easy to author your
After downloading and installing, start JDeveloper. If you are behind a proxy, configure the proxy using:
Tools > Preferences > Web Browser and Proxy
Next we will add the
| Schema: | http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd |
|---|---|
| Extension: | xml |
Press OK and now your JDeveloper is ready to edit your
TortoiseSVN is a graphical front end to Subversion. It also has the capability to create a file based repository. We will use this feature for this tutorial. There is no need for you to have access to a Subversion server. Download TortoiseSVN from http://tortoisesvn.net/. Install it and reboot your PC.
Create the directory structure for this tutorial.
D: mkdir D:\projects\lbdemo\repo
In Windows Explorer, right-click on directory repo and choose TortoiseSVN > Create repository here. We have now created a Subversion repository.
Right-click on the directory repo again, and choose TortoiseSVN > Repo-browser. The browser displays in a window similar to Windows Explorer. Right-click on the repo directory and choose Create folder ... Enter the name: trunk
. You will then be prompted for a comment before you commit this change. Enter any comment.
Repeat this to create folders branches
and tags
.
You should end up with a repository structure that looks like this:
file:///D:/projects/lbdemo/repo +- branches +- tags +- trunk
Close the repository browser.
Return to Windows Explorer, navigate to directory D:\projects\lbdemo and right-click in the right panel. Choose SVN Checkout. In the panel that appears, enter:
| URL of repository: | file:///D:/projects/lbdemo/repo/trunk
|
|---|---|
| Checkout directory: | D:\projects\lbdemo\trunk
|
Press OK. A confirmation window will display to create directory trunk. Select Yes. Press OK. In Windows Explorer, the trunk directory will be displayed with a green icon, indicating that it is a working copy with no changes to commit.
Download the Oracle JDBC driver here: http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.
Click on the link for 10g Release 2 drivers, and choose ojdbc14.jar
.
Save the jar in directory: D:\projects\lbdemo
.
Install
Add the directory containing the Liquibase.bat
file to your PATH. Redmond Path is a handy tool to edit your path; much easier than the standard facility in Windows.
Test the installation by opening a DOS box in the D:\projects\lbdemo\trunk
directory and entering the following command:
Liquibase --version
The result should be something like: Liquibase Version: 1.9.0
Next, create a file named Liquibase.properties.template
in the trunk
directory with the following contents:
#Liquibase.properties driver: oracle.jdbc.OracleDriver classpath: ../ojdbc14.jar url: jdbc:oracle:thin:@localhost:1521:XE username: tbd password: tbd
Note that the classpath is relative to the current directory.
Copy this file to Liquibase.properties
and edit the last 2 lines to look like this:
#Liquibase.properties driver: oracle.jdbc.OracleDriver classpath: ../ojdbc14.jar url: jdbc:oracle:thin:@localhost:1521:XE username: lb_dev password: lb_dev
This properties file will save us from specifying these parameters on the command line. We will check the template file into subversion. The file with the real connection details we will keep locally.
Right-click on file Liquibase.properties
and choose TortoiseSVN > Add to ignore list > Liquibase.properties
Right-click on file Liquibase.properties.template
and choose TortoiseSVN > Add
Right-click on directory trunk
and choose TortoiseSVN > commit.
For our tutorial, we will create these database schemas:
Open SQL Developer and create a connection to your database using the "system" username.
File > New > Connections > Database connection
Open this connection and run these commands:
drop user lb_dev cascade; create user lb_dev identified by lb_dev; grant connect, resource, create view to lb_dev; drop user lb_test cascade; create user lb_test identified by lb_test; grant connect, resource, create view to lb_test; drop user lb_solo cascade; create user lb_solo identified by lb_solo; grant connect, resource, create view to lb_solo; drop user lb_duplex cascade; create user lb_duplex identified by lb_duplex; grant connect, resource, create view to lb_duplex;
In SQL Developer, create a connection for each of these users. They will come in handy later.
In this step we will be creating the following directory structure in the trunk
directory:
trunk +-- install | +-- cst <-- Contains FK constraints, one file per table | +-- seq <-- Contains sequence definitions, one file per sequence | +-- tab <-- Contains table definitions, one file per table +-- latest | +-- pkb <-- Contains package bodies, one file per package | +-- pks <-- Contains package specifications, one file per package | +-- trg <-- Contains triggers, one file per trigger | +-- vw <-- Contains views, one file per view +-- v000
We will create a separate install directory for the installation of non-replaceable objects (as opposed to the upgrades), and within the install directory a separate directory for each type of object.
Under latest, we have a directory for each type of "replaceable" database object. By "replaceable" we mean that the object can be updated by simply replacing it by a new version. The SQL syntax for these objects starts with create or replace
.
Paste these commands in a DOS box to create the directory structure in one go:
cd \projects\lbdemo\trunk mkdir install mkdir install\cst mkdir install\seq mkdir install\tab mkdir latest mkdir latest\pkb mkdir latest\pks mkdir latest\trg mkdir latest\vw mkdir v000
As we are starting from scratch (version 0), directory v000 will contain the
We'll create a simple batch file to perform the upgrades:
trunk/lb_update.bat
@echo off call Liquibase --changeLogFile=update.xml update
The file above refers to update.xml
, which we will create next.
JDeveloper is a great tool for editing XML files, but creating a new XML file from scratch is a bit cumbersome. The following steps are the quickest way:
trunk/update.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <include file="v000/master.xml" /> </databaseChangeLog>
Create the file that will later contain the includes of each
trunk/v000/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 0 --> <sqlCheck expectedResult="0"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> </databaseChangeLog>
You may be wondering why this file contains a preCondition. Doesn't
Commit the current version to Subversion. Right-click on directory trunk and select SVN Commit
Enter a message like "Initial version", select all files/directories and press OK. Now the files/directories will also be displayed with a green icon in Windows explorer.
Each change (including initial creations) are related to an issue number: a bug or a project task. Our first task (which happens to have number 73) is to create 2 tables.
The file structure which we will be describing has a certain structure which is easier to see if we visualize it. The white boxes are the directories. The blue boxes are the files within the directories. The arrows indicate that one file calls or includes another file.
The description of this task is:
departments
, the primary key is populated using a sequence and a trigger
employees
with a foreign key to departments
We will create one changefile for these changes. It will consist of these changes:
latest/trg
Create the following files:
trunk/v000/2009-10-15-73.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <createTable tableName="departments" remarks="The departments of this company. Does not include geographical divisions."> <column name="id" type="number(4,0)"> <constraints nullable="false" primaryKey="true" primaryKeyName="DPT_PK"/> </column> <column name="dname" type="varchar2(14)" remarks="The official department name as registered on the internal website."/> </createTable> <addUniqueConstraint constraintName="departments_uk1" columnNames="dname" tableName="departments"/> <createSequence sequenceName="departments_seq"/> </changeSet> <include file="latest/trg/departments_bi.xml"/> <changeSet author="jsmith" id="2"> <createTable tableName="employees"> <column name="id" type="number(4,0)"> <constraints nullable="false" primaryKey="true" primaryKeyName="EMP_PK"/> </column> <column name="ename" type="varchar2(14)" remarks="The first and last name"/> <column name="salary" type="number(6,2)" remarks="The full remuneration"/> <column name="dpt_id" type="number(4,0)"/> </createTable> <addForeignKeyConstraint baseColumnNames="dpt_id" baseTableName="employees" constraintName="emp_dpt_fk" referencedColumnNames="id" referencedTableName="departments"/> </changeSet> </databaseChangeLog>
The table and column remarks will be applied as table and column comments in the database.
trunk/latest/trg/departments_bi.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1" runOnChange="true"> <createProcedure>create trigger departments_bi before insert on departments for each row when (new.id is null) begin select departments_seq.nextval into :new.id from dual; end; </createProcedure> <rollback> drop trigger departments_bi </rollback> </changeSet> </databaseChangeLog>
The runOnChange="true" attribute. This ensures that we can make future changes in this file and these changes will be applied automatically. Note also that in the file above, we have provided an explicit rollback statement to undo this change.
Update the master.xml to include the change:
trunk/v000/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 0 --> <sqlCheck expectedResult="0"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v000/2009-10-15-73.xml" /> </databaseChangeLog>
Now we are ready to test the changes by applying them to the database. Run the batch file we created before:
D:\projects\lbdemo\trunk> lb_update
If all goes well, you will see a confirmation message: Migration successful.
Now examine the contents of table
Liquibase --changeLogFile=update.xml rollbackCountSQL 3
To actually perform the rollback:
Liquibase --changeLogFile=update.xml rollbackCount 3
After you have completed and tested your changes, commit them to Subversion with this comment: "73: Create tables departments & employees". The current state is represented by the first box on the diagram at the start of this tutorial.
This task is now complete, we will continue to the next task.
This description of this task is:
departments_pck
departments_vw
Both objects are of the "replaceable" type, i.e. a new version can simply replace an older version. The files will therefore go into the latest
directory. Create/update the following files:
trunk/v000/master.xml (add the new change to the end of the file)
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 0 --> <sqlCheck expectedResult="0"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v000/2009-10-15-73.xml" /> <include file="v000/2009-10-15-59.xml" /> </databaseChangeLog>
trunk/v000/2009-10-15-59.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <include file="latest/pks/departments_pck.xml"/> <include file="latest/pkb/departments_pck.xml"/> <include file="latest/vw/departments_vw.xml"/> </databaseChangeLog>
trunk/latest/pks/departments_pck.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1" runOnChange="true"> <createProcedure>create or replace package departments_pck as function upname(name in varchar2) return varchar2; end departments_pck; </createProcedure> <rollback> drop package departments_pck </rollback> </changeSet> </databaseChangeLog>
trunk/latest/pkb/departments_pck.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1" runOnChange="true"> <createProcedure>create or replace package body departments_pck as function upname(name in varchar2) return varchar2 is begin return upper(name); end; end departments_pck; </createProcedure> <rollback> drop package body departments_pck </rollback> </changeSet> </databaseChangeLog>
trunk/latest/vw/departments_vw.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1" runOnChange="true"> <createView viewName="departments_vw"> select id, dname from departments </createView> </changeSet> </databaseChangeLog>
Now we are ready to test the changes by applying them to the database. Run the batch file we created before:
D:\projects\lbdemo\trunk> lb_update
If all goes well, you will see a confirmation message: Migration successful.
Now examine the contents of table
Liquibase --changeLogFile=update.xml rollbackCount 3
After you have completed and tested your changes, commit them to Subversion with comment:"59: create departments_pck and departments_vw".
We could continue in this manner for the remainder of the project. At some point however, the number of changes may become very large and we may want to define a new starting point. This is the topic of the next section.
We are ready to branch for release 1.x. This will allow us to perform a fresh install of version 1.x, without applying the many changes from 0.0 to 1.0. Of course, for installations running version 0.x, we also provide the incremental migration possibility.
The last change to version 0 has been made. After all these changes have been applied, we are effectively at major version 1. The major version is recorded in table
trunk/v000/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!--These changes should only be run against a schema with major version 0--> <sqlCheck expectedResult="0"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v000/2009-10-15-73.xml"/> <include file="v000/2009-10-15-59.xml"/> <!-- Do not include any more changes in this file --> <changeSet author="MajorVersion" id="1" /> </databaseChangeLog>
Run the update command to apply the
lb_update
So there is room here for a new utility (watch this space!).
For now, we will create the installation
latest
directory, as we have seen before.
install
directory.
Our (manual) utility will create these files:
trunk/install/tab/departments.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <createTable tableName="departments" remarks="The departments of this company. Does not include geographical divisions."> <column name="id" type="number(4,0)"> <constraints nullable="false" primaryKey="true" primaryKeyName="DPT_PK"/> </column> <column name="dname" type="varchar2(14)" remarks="The official department name as registered on the internal website."/> </createTable> <addUniqueConstraint constraintName="departments_uk1" columnNames="dname" tableName="departments" /> </changeSet> </databaseChangeLog>
trunk/install/tab/employees.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <createTable tableName="employees"> <column name="id" type="number(4,0)"> <constraints nullable="false" primaryKey="true" primaryKeyName="EMP_PK"/> </column> <column name="ename" type="varchar2(14)" remarks="The first and last name"/> <column name="salary" type="number(6,2)" remarks="The full remuneration"/> <column name="dpt_id" type="number(4,0)"/> </createTable> </changeSet> </databaseChangeLog>
trunk/install/seq/departments_seq.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <createSequence sequenceName="departments_seq"/> </changeSet> </databaseChangeLog>
trunk/install/cst/employees.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <addForeignKeyConstraint baseColumnNames="dpt_id" baseTableName="employees" constraintName="emp_dpt_fk" referencedColumnNames="id" referencedTableName="departments"/> </changeSet> </databaseChangeLog>
Create a new directory for the
mkdir v001
Create a new master.xml in this directory:
trunk/v001/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 1 --> <sqlCheck expectedResult="1"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> </databaseChangeLog>
Edit the update file:
trunk/update.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <include file="v001/master.xml" /> </databaseChangeLog>
Create the install script for fresh installs of version 1.x:
trunk/lb_install.bat
@echo off call Liquibase --changeLogFile=install.xml update call Liquibase --changeLogFile=update.xml update
As you can see above, after the installation of 1.x, we run the updates from 1.x to the latest version. You may wonder: why not include the update at the end of the install.xml file as: <include file="v001/master.xml" />
? That would be equally valid. However, for some reason, if we do that then the precondition in master.xml fails.
Create the install.xml
. This file does the fresh install of objects, records the MajorVersion number and includes new changes from version v001 (see last 2 lines in script below):
trunk/install.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <includeAll path="install/tab/" /> <includeAll path="install/seq" /> <includeAll path="install/cst" /> <includeAll path="latest/pks" /> <includeAll path="latest/vw" /> <includeAll path="latest/pkb" /> <includeAll path="latest/trg" /> <changeSet author="MajorVersion" id="1" /> </databaseChangeLog>
Modify
username: lb_test password: lb_test
Perform the fresh install in schema lb_test:
lb_install
This should run successfully.
Modify
username: lb_dev password: lb_dev
To verify that the fresh install in lb_test is identical to the incrementally built schema in lb_dev we can use the
liquibase --url=jdbc:oracle:thin://localhost:9090/mem:test --username=user1 --password=password --referenceUrl=jdbc:oracle:thin:@localhost:1521:XE --referenceUsername=lb_test --referencePassword=lb_test diff
This command will give the output in text format and should indicate that there are no differences:
Diff Results: Base Database: LB_TEST jdbc:oracle:thin:@localhost:1521:XE Target Database: LB_DEV jdbc:oracle:thin:@localhost:1521:XE Product Name: EQUAL Product Version: EQUAL Missing Tables: NONE Unexpected Tables: NONE Missing Views: NONE Unexpected Views: NONE Missing Columns: NONE Unexpected Columns: NONE Changed Columns: NONE Missing Foreign Keys: NONE Unexpected Foreign Keys: NONE Missing Primary Keys: NONE Unexpected Primary Keys: NONE Missing Unique Constraints: NONE Unexpected Unique Constraints: NONE Missing Indexes: NONE Unexpected Indexes: NONE Missing Sequences: NONE Unexpected Sequences: NONE
diffChangeLog
command in the manual.
Release 1.x is technically correct now, ready for branching.
Commit the current version to Subversion. Right-click on directory trunk and select SVN Commit. Include all the newly created files.
Enter a message like "Finalize 1.x", select all files and press OK. Now the files will also be displayed with a green icon in Windows explorer.
Right-click on the trunk
and choose TortoiseSVN > Repo-browser. Select trunk
in the left pane. By default we are selecting the HEAD, which is correct. But if someone else commited a change on the trunk in the meantime, you would want to select the revision in which you finalized 1.x.
Right-click on trunk
and choose copy to ..
.
Fill in:
| New Name: | file:///D:/projects/lbdemo/repo/branches/1.x |
|---|
Enter log message "Branched 1.x" and press OK.
In the left pane under branches you will now see a folder named 1.x. Right-click on branches/1.x
and choose Checkout.
| URL of repository: | file:///D:/projects/lbdemo/repo/branches/1.x |
|---|---|
| Checkout directory: | D:\projects\lbdemo\branch_1.x |
The new directory will be created, containing the files in this branch. The system test can start, to verify that this version is fit to ship.
Let's do a fresh install from this directory into the lb_test schema.
Navigate to directory branch_1.x
and copy file Liquibase.properties.template
to Liquibase.properties
. Change the connection details to:
username: lb_test password: lb_test
Re-create the lb_test schema again using SQLDeveloper. Connect as system and run:
drop user lb_test cascade; create user lb_test identified by lb_test; grant connect, resource, create view to lb_test;
Perform the fresh install from the directory branch_1.x
:
cd \projects\lbdemo\branch_1.x lb_install
In order to test data migration functionality, let's insert some test data. In a SQL Developer session, run this script:
insert into departments (id, dname) values (1, 'HQ'); insert into departments (id, dname) values (2, 'Sales'); insert into employees (id, ename, salary, dpt_id) values (1, 'King', 1200, 1); insert into employees (id, ename, salary, dpt_id) values (2, 'Smith', 1000, 2); commit;
Run this script in the lb_dev schema and in the lb_test schema. We won't create
The system test on version 1.x has revealed a bug and it needs to be fixed before we can ship version 1.0. We fix bugs on the trunk, and then backport them to the relevant branches.
This change has been registered in our issue tracker with number 102. The change description is:
Remember that our changes are now taking us from version 1.x, so the
trunk/v001/2009-10-16-102.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <addColumn tableName="employees"> <column name="fixed_salary" type="number(6,2)" remarks="Monthly gross salary"/> <column name="bonus" type="number(6,2)" remarks="On-target monthly bonus"/> </addColumn> <update tableName="employees"> <column name="fixed_salary" valueNumeric="salary * 0.9"/> <column name="bonus" valueNumeric="salary * 0.1"/> </update> <addNotNullConstraint tableName="employees" columnName="fixed_salary" /> <addNotNullConstraint tableName="employees" columnName="bonus" /> <dropColumn tableName="employees" columnName="salary" /> </changeSet> </databaseChangeLog>
Update master.xml
to include this file:
trunk/v001/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 1 --> <sqlCheck expectedResult="1"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v001/2009-10-16-102.xml"/> </databaseChangeLog>
Run the update command:
lb_update
This change cannot be rolled back automatically. If we wanted to be able to roll this back, we would have had to specify the rollback logic.
Use SQL Developer to check that the changes have successfully been applied.
DESC employees ame Null Type -------------------- -------- ------------ ID NOT NULL NUMBER(4) ENAME VARCHAR2(14) DPT_ID NUMBER(4) FIXED_SALARY NOT NULL NUMBER(6,2) BONUS NOT NULL NUMBER(6,2) 5 rows selected SELECT * FROM employees; ID ENAME DPT_ID FIXED_SALARY BONUS ---- --------- --------- -------------- ----- 1 King 1 1080 120 2 Smith 2 900 100 2 rows selected
Commit these changes using TortoiseSVN. Enter log message: "102: Replace salary by fixed_salary and bonus".
Right-click on directory branch_1.x
and choose TortoiseSVN > Merge.
| Merge type: | Merge a range of revisions |
|---|
Press Next
| URL to merge from: | file:///D:/projects/lbdemo/repo/trunk |
|---|---|
| Revision range to merge: | Use the [Show log] button to display the list of revisions. Select the change for bug 102. |
Press Next
Press Merge
Press OK to close the results window.
In Windows Explorer, you will see that 2009-10-16-102.xml
has been added to the v001 directory, and that v001/master.xml
has been updated. Right-click on file master.xml
and choose TortoiseSVN > Diff. You will see that only the one line has been added to master.xml.
Commit branch_1.x with comment "102: backport".
Run the update command:
cd D:\projects\lbdemo\branch_1.x lb_update
Use SQL Developer to confirm that the employees in schema lb_test now have a fixed salary and a bonus.
The acceptance test has now been completed, so we can label this version as our "1.0" release.
Right-click on branch_1.x
and choose TortoiseSVN > Branch/Tag. Fill out the dialogue as shown below:
| From WC at URL: | file:///D:/projects/lbdemo/repo/branches/1.x |
|---|---|
| To URL: | file:///D:/projects/lbdemo/repo/tags/1.0 |
| Create copy in the repository from: | (leave as default) |
| Log message: | Tagged as 1.0 |
Press OK and close the repository browser.
We can now deliver version 1.0 to the customer.
We can now deliver version 1.0 to our customer Solo. Create directory D:\projects\lbdemo\solo
. Right-click on this directory and choose TortoiseSVN > Export. Fill out the dialogue as shown below:
| URL of repository: | file:///D:/projects/lbdemo/repo/tags/1.0 |
|---|---|
| Export directory: | D:\projects\lbdemo\solo |
Leave the rest as default and press OK. The files will be exported to the solo directory.
Copy file Liquibase.properties.template
to Liquibase.properties
and change the username and password to lb_solo
.
Apply the
cd D:\projects\lbdemo\solo lb_install
Twice, you should receive the confirmation "Migration successful", and Solo is running on 1.0.
The specifications for this change are:
Create the
trunk/v001/2009-10-16-105.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <addColumn tableName="departments"> <column name="mgr_id" type="number(4,0)"/> </addColumn> <sql>update departments set mgr_id = (select id from employees where ename='King'); </sql> <addForeignKeyConstraint baseColumnNames="mgr_id" baseTableName="departments" constraintName="dpt_emp_fk1" referencedColumnNames="id" referencedTableName="employees"/> </changeSet> </databaseChangeLog>
Update master.xml
to include this file:
trunk/v001/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 1 --> <sqlCheck expectedResult="1"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v001/2009-10-16-102.xml"/> <include file="v001/2009-10-16-105.xml"/> </databaseChangeLog>
Run the update command:
lb_update
Use SQL Developer to check that the changes have been applied correctly.
Commit these changes using TortoiseSVN, with comment "105: Add mgr_id and foreign key".
This is the same as step 5. Repeat step 5 , replacing 1.x by 2.x.
However, there is a difference. Customers running 1.x need to be able to upgrade to 2.x. We did not cover that aspect previously. If a 1.x customer were simply to run lb_update, then it would fail on the precondition in the master.xml:
<preConditions> <!-- These changes should only be run against a schema with major version 2 --> <sqlCheck expectedResult="2"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions>
So how do we ensure that all the changes between "finalize 1.x" and "finalize 2.x" have been applied before applying the 2.x changes? If you look at the diagram at the beginning of this tutorial, you will see that we are talking about change 105. Change 105 was never delivered in the 1.x branch and it is not contained in the v002/master.xml.
The answer is, we create 2 new files as part of step 5.3:
trunk/lb_upgrade_to_major.bat
@echo off call Liquibase --changeLogFile=upgrade_to_major.xml update call Liquibase --changeLogFile=update.xml update
trunk/upgrade_to_major.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <include file="v001/master.xml" /> </databaseChangeLog>
Testing on branch 2.x revealed a bug that we want fixed on branch 1.x as well. Column employees.ename needs to be renamed to full_name. Refer to the diagram at the start of this tutorial for a visual overview of this step. By now you should know the routine.
Create the
trunk/v002/2009-10-18-114.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <changeSet author="jsmith" id="1"> <renameColumn newColumnName="full_name" oldColumnName="ename" tableName="employees"/> </changeSet> </databaseChangeLog>
Update master.xml
to include this file:
trunk/v002/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 2 --> <sqlCheck expectedResult="2"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v002/2009-10-18-114.xml"/> </databaseChangeLog>
Run the update command:
lb_update
Use SQL Developer to check that the changes have been applied correctly.
Commit these changes using TortoiseSVN, with comment "114: Renamed employee.ename to full_name".
This is the same as step 8 with a major exception. On the trunk, change 114 is recorded in directory v002 and in file v002/master.xml
Branch 1.x does not have a directory v002. We will create this directory to contain the v002/master.xml
. There should only be one master.xml on a branch, as it contains the order of the changes.
Change 114 will be referenced in v001/master.xml
as follows:
branch_1.x/v001/master.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"> <preConditions> <!-- These changes should only be run against a schema with major version 1 --> <sqlCheck expectedResult="1"> SELECT NVL(MAX(id),0) FROM databasechangelog WHERE author='MajorVersion' </sqlCheck> </preConditions> <include file="v001/2009-10-16-102.xml"/> <include file="v002/2009-10-18-114.xml"/> </databaseChangeLog>
This is the same as step 8.
This is the same as step 9, except you will run the lb_update command instead of lb_install to update Solo to the latest version of the 1.x branch.
This is also the same as step 9, but taking the export from tag 2.0.
The same export created in the previous step can be delivered to customer Solo.
Customer lb_solo runs the lb_upgrade_to_magor
command.
The default action is to create a change file named <date>-IssueNr>.xml in directory vXXX and specify the change in this file. Example filename: v002/2009-12-25-305.xml
| Create | Modify | Delete | |
|---|---|---|---|
| Table | Default | Default | Default |
| Sequence | Default | Default | Default |
| View | Create new file in directory latest/vw . Include this file in the change file. |
Modify file in directory latest/vw . Include this file in the change file. |
See below |
| Trigger | Create new file in directory latest/trg . Include this file in the change file. |
Modify file in directory latest/trg . Include this file in the change file. |
See below |
| Package | Create new file in directory latest/pck . Include this file in the change file. |
Modify file in directory latest/pck . Include this file in the change file. |
See below |
The procedure is described here for a view, and is similar for triggers and packages.
Delete the view from the latest/vw
directory.
Create a changeset to delete the view, with a preCondition. The preCondition prevents an error condition if the view does not exist. This will be the case if we run a
<changeSet author="jsmith" id="1"> <preConditions onFail="MARK_RAN"> <viewExists viewName="departments_vw"> </preConditions> <dropView viewName="departments_vw"/> </changeSet>
alternative
<changeSet author="jsmith" id="1" failOnError="false"> <dropView viewName="departments_vw"/> </changeSet>
Add the changeset to the master.
Search all
As an example, let's assume that you are ready to branch for release 4.x.
The trunk will contain:
On the trunk, perform the following actions:
Create a branch from this revision with name "4.x". The x indicates that all further patches on 4.0 will take place on this branch. Development of 4.1 will take place on the trunk.


Reports redundant conversion method call (toInt
, toString
, and so on).
A conversion is redundant if the conversion doesn't change the type of the collection.
Example:
"Test".toString
Seq(1, 2).toSeq
After the quick-fix is applied:
"Test"
Seq(1, 2)


CHM | Aug 2021 | IISER Pune
Mail Index
Choose your mail index. [Only useful if you are on Desktop]
Read this page for help and info.
The Classroom, Drive and Search Mail links depend on the mail index.
Current Mail Index = 1
CH 3114
Physical Organic Chemistry
CH 3124
Main Group Chemistry
CH 3143
Self-Assembly in Chemistry
CH 3154
Chemical Equilibrium and Kinetics
CHM 411
Organic Synthesis 2
CHM 413
Bioinorganic Chemistry
CHM 421
Polymer Chemistry
CHM 431
Chemical Biology
CHM 432
Solid State Chemistry
CHM 445
Electrochemistry
CHM 446
Fundamentals of Solution State NMR Spectroscopy


NCSC researcher
Senior security researcher from NCSC.
Talk: Good Security Made Easier with Serverless
The National Cyber Security Centre (NCSC) has been researching the security properties of serverless components in the public cloud to identify the impact serverless has on security. As the research nears its conclusion, we discuss our thoughts and experiences with serverless technology.
Back to the agenda


Just some maths notes to myself…
Note: Typically you have to string these formulas together. Look in the table for what you want, and what you have. If the two are not the same line, than you need conversion steps inbetween. E.g. if you have an angle in degrees, but the formula expects radians: 1) convert degrees to radians, 2) use the radians formula on the result.
| I have… | I want… | Formula |
|---|---|---|
| normalized direction and length n1,d1 | a vector that goes that far in that direction new direction vector v0 | v0 = n1.mult(d1) |
| point and direction vector p1,v1 | to move the point new point p0 | p0 = p1.add(v1) |
| two direction vectors or normals v1,v2 | to combine both directions new direction vector v0 | v0 = v1.add(v2) |
| two points p1, p2 | distance between two points new scalar d0 | d0 = p1.subtract(p2).length() d0 = p1.distance(p2) |
| two points p1, p2 | the direction from p2 to p1 new direction vector v0 | v0 = p1.substract(p2) |
| two points, a fraction p1, p2, h=0.5f | the point "halfway" (h=0.5f) between the two points new interpolated point p0 | p0 = FastMath.interpolateLinear(h,p1,p2) |
| I have… | I want… | Formula |
|---|---|---|
| angle in degrees a | to convert angle a from degrees to radians new float angle phi | phi = a / 180 * FastMath.PI; OR phi=a.mult(FastMath.DEG_TO_RAD); |
| angle in radians phi | to convert angle phi from radians to degrees new float angle a | a = phi * 180 / FastMath.PI |
| radian angle and x axis phi, x | to rotate around x axis new quaternion q0 | q0.fromAngleAxis( phi, Vector3f.UNIT_X ) |
| radian angle and y axis phi, y | to rotate around y axis new quaternion q0 | q0.fromAngleAxis( phi, Vector3f.UNIT_Y ) |
| radian angle and z axis phi, z | to rotate around z axis new quaternion q0 | q0.fromAngleAxis( phi, Vector3f.UNIT_Z ) |
| several quaternions q1, q2, q3 | to combine rotations, in that order new quaternion q0 | q0 = q1.mult(q2).mult(q3) |
| point and quaternion p1, q1 | to rotate the point around origin new point p0 | p0 = q1.mult(p1) |
| angle in radians and radius phi,r | to arrange or move objects horizontally in a circle (with y=0) x and z coordinates | float x = FastMath.cos(phi)*r; float z = FastMath.sin(phi)*r; |
v2 = v.mult(); v2 = v.add(); v2 = v.subtract(); etc
v.multLocal(); v.addLocal(); v.subtractLocal(); etc


1. Double check that you have included capital letters and there are no spaces at the start or end
2. Check that the version number you have entered is valid.
Go to Services > System Setup > System Details to find your box's version number.
3. Is your version number valid but no output is showing? This means the version number is not
in this website's database.Contact us
here with the version number
and we'll add it to the database as soon as we can.


INSTRUCTIONS: Use the arrow keys to move the green snake around the
screen and eat the red food to score points.
The button turns on Vim Mode
which diasbles the arrow keys and enables Vim directional keys (hjkl).
The button turns on Portal
Mode which adds portals to the board so you can transcend both time
and space. Guess what the
does? Increases the speed! Also, the walls are currently set to off
so you can pass through them. Click the
to turn them on if you're
the real deal. WATCH OUT - those modes might just go ahead and turn
themselves on if you score enough points!


Watch the trailer for new posthumous Lil Peep album ‘Everybody’s Everything’
The album accompanies a new documentary about the late rapper, also due to arrive this month
Another posthumous Lil Peep album, ‘Everybody’s Everything’, has been officially announced to coincide with the release of a new documentary about the rapper.
The album will feature a variety of tracks from various stages in Peep’s career, including previously unreleased songs and older songs that have never been made available on all platforms. The record includes a number of high profile guest artists, including iLoveMakonnen, Lil Tracy and Rich The Kid. Watch the album trailer below.
The documentary, also titled Everybody’s Everything, is due out in US cinemas on November 12, with the album to follow on November 15.
Lil Peep – real name Gustav Åhr – died on November 15, 2017 of an accidental overdose, aged 21. The documentary about Peep is described as “an intimate, humanistic portrait that seeks to understand an artist who attempted to be all things to all people” in its official synopsis.
The feature-length film was co-directed by Sebastian Jones and Ramez Silyan, and executive produced by acclaimed filmmaker Terrence Malick, Peep’s mother Liza Womack and Sarah Stennett, the CEO of First Access Entertainment who had advised the rapper on his career.
The Everybody’s Everything trailer, released September 29, shows home videos of Peep as a child as well as clips of the rapper playing shows, making music, sitting for interviews and meeting fans. There are also excerpted interviews with Peep’s family and his friends, including Post Malone and iLoveMakonnen. Watch it below.
‘Everybody’s Everything’ tracklist:
1. ‘Liar’
2. ‘AQUAFINA’ (ft. Rich The Kid)
3. ‘RATCHETS’ (ft. Lil Tracy)
4. ‘Rockstarz’ (ft. Gab3)
5. ‘LA To London’ (ft. Gab3)
6. ‘Fangirl’ (ft. Gab3)
7. ‘Text Me’ (ft. Era)
8. ‘PRINCESS’
9. ‘Moving On’
10. ‘Belgium’
11. ‘When I Lie’
12. ‘I’ve Been Waiting’ (ft. iLoveMakonnen) (Original Version)
13. ‘Live Forever’
14. ‘ghost boy’
15. ‘Keep My Coo’
16. ‘white tee’ (ft. Lil Tracy)
17. ‘cobain’ (ft. Lil Tracy)
18. ‘witchblades’ (ft. Lil Tracy)
19. ‘walk away as the door slams’ (acoustic) (ft. Lil Tracy)
Currently available for pre-order, the album will be released in a variety of bundles and formats, including a 2LP set with previously unseen photos of the artist.
Last November, Peep’s family released ‘Come Over When You’re Sober Pt. 2’, the rapper’s first posthumous album. In a four-star review, NME said: “A high-water mark in Peep’s work, it reminds listeners of the talent Gustav Åhr possessed and how we were deprived of it all too early.”


${project.name} ${project.version}
Overview
High-level details about this library can be found at google-api-java-client
Dependencies and Licenses
The license can be found
here.
Dependent jars can be found in the
libs folder and the corresponding source jars can be found
in the
libs-sources folder.
The dependency structure and licenses for the different libraries can
be found here:
Maven Usage
For information on how to add these libraries to your Maven project please see
Maven.
Eclipse
A .classpath file snippet that can be included in your project's .classpath
has been provided
here. Please only use the classpathentry's you
actually need (see below for details).
ProGuard
A ProGuard configuration file proguard-google-api-client.txt
is included for common settings for using the library. On Android projects,
you may want to add a reference to
proguard-google-api-client.txt
in the
project.properties
file under the
proguard.config
property.
Please read Setup
ProGuard for more details.
Dependencies for all Platforms
The following are the jars from the
libs folder needed for applications on all platform:
- google-api-client-${project.version}.jar
- google-oauth-client-${project.oauth.version}.jar
- google-http-client-${project.http.version}.jar
- jsr305-${project.jsr305.version}.jar
- google-api-client-protobuf-${project.api.version}.jar (when using
protobuf-java)
- google-http-client-protobuf-${project.http.version}.jar
- protobuf-java-${project.protobuf-java.version}.jar
- google-api-client-gson-${project.api.version}.jar (when using
GSON)
- google-http-client-gson-${project.http.version}.jar
- gson-${project.gson.version}.jar
- google-api-client-jackson2-${project.api.version}.jar (when using
Jackson 2)
- google-http-client-jackson2-${project.http.version}.jar
- jackson-core-${project.jackson-core2.version}.jar
- google-api-client-xml-${project.version}.jar (when using XML)
- google-http-client-xml-${project.version}.jar
- xpp3-${project.xpp3.version}.jar (when NOT on Android)
Android Dependencies
The following are the jars from the
libs folder required for Android applications:
- google-api-client-android-${project.version}.jar (for SDK >= 2.1)
- google-http-client-android-${project.http.version}.jar
The
libs folder also contains properties files that specify the
location of source jars for Android projects in Eclipse.
Please see the
Android
for the Android Developer's Guide.
Google App Engine Dependencies
The following are the jars from the
libs folder required for Google App Engine applications or
a newer compatible version:
- google-api-client-appengine-${project.version}.jar
- google-api-client-servlet-${project.version}.jar
- google-oauth-client-appengine-${project.oauth.version}.jar
- google-oauth-client-servlet-${project.oauth.version}.jar
- google-http-client-appengine-${project.http.version}.jar
- jdo2-api-${project.jdo2-api.version}.jar
- transaction-api-${project.transaction-api.version}.jar
Please see the
GoogleAppEngine
wiki for the Google App Engine Developer's Guide.
Servlet Dependencies
The following are the jars from the
libs folder required for Servlet applications or a newer
compatible version:
- google-api-client-servlet-${project.version}.jar
- google-oauth-client-servlet-${project.oauth.version}.jar
- commons-logging-${project.commons-logging.version}.jar
- httpclient-${project.httpclient.version}.jar
- httpcore-${project.httpcore.version}.jar
- jdo2-api-${project.jdo2-api.version}.jar
- transaction-api-${project.transaction-api.version}.jar
General Purpose Java 5 Environment Dependencies
The following are the jars from the
libs folder required for general purpose Java 5
applications or a newer compatible version:
- google-api-client-java6-${project.version}.jar
- google-oauth-client-java6-${project.oauth.version}.jar (for JDK >=
6)
- google-oauth-client-jetty-${project.oauth.version}.jar (for
Jetty 6)
- jetty-${project.jetty.version}.jar
- jetty-util-${project.jetty.version}.jar
- google-oauth-client-java7-${project.version}.jar (for JDK >= 7)
- commons-logging-${project.commons-logging.version}.jar
- httpclient-${project.httpclient.version}.jar
- httpcore-${project.httpcore.version}.jar


--- layout: post title: shake shake shake date: 2012-05-29 03:27:04.000000000 -04:00 type: post published: true status: publish categories: - college - nyc tags: - asiadog - MOMA - nyc - shake shack meta: _edit_last: '1' author: login: sophie email<EMAIL_ADDRESS>display_name: Pika first_name: '' last_name: '' ---
Yesterday my dear friend Lyndsey came to visit and we had quite a delicious day!
We are both big fans of art and so we spent the whole afternoon exploring the MOMA. We managed to go through every room on every floor, in just a bit more than 2 hours!
After that we made a beeline for Shake Shack, New York's most popular burger and shake chain. Unfortunately, it's also a tourist favorite, and so the line for burgers was ridiculously long. We settled for sweets instead, since the line for cold food was much shorter.
This is a "Concrete", which according to Shake Shack's menu is "Dense frozen custard blended at high speed with toppings & mix-ins". I got the Shack Attack® :Chocolate custard, fudge sauce, chocolate truffle cookie dough and Mast Brothers Shake Shack blend chocolate, topped with chocolate sprinkles.
Lyndsey got good ol' plain chocolate, a familiar favorite.
We both thought it was more like soft ice cream than a shake. In fact, I couldn't really tell what made it a "concrete". Of course, ice cream is always welcome on a hot, muggy day, but maybe I would just go for the cheaper alternative next time.
Thank goodness Madison Square Eats (a mini food stand fest) was going on across the street! All the food looked amazing, and I choose to try the vegetarian Mel + Steve (asian sesame slaw on top of veggie dog) from AsiaDog, an Asian Fusion hot dog stand.
Lyndsey and I both agreed it was by far the prettiest hot dog (with the purple cabbage slaw) that we'd ever seen! And the taste was great, too :)
Note: Later that night I actually went to Shake Shack AGAIN, for a hackNY team-building event, and got to try the famous 'Shroom Burger (deep fried portabello stuffed with Muenster), with cheese fries on the side.  I don't see anything great in the shakes, but the hot food at Shake Shack is greasy goodness.
This is how I felt after feasting all day:


Search your friend's username
Select his or her username
No new player to add, come back later !
Send request
Go back to my profile


FKFD.ME
Not a replica of xkcd
®©™
< Prev
Random
Next >
< Prev
GOTO
Next >
Pro Tip:
Technically
you can goto a comic with URL hash.


Save over £100 on these Sony Wh-XB900N wireless noise cancelling headphones
by https://www.facebook.com/LouderPosts/Black Friday is a week away but the deals have already started, as these Sony headphones prove
Black Friday is officially a week away, but that hasn't stopped the major retailers from starting their sales now.
 With overpowering bass., balanced mids and detailed highs, an impressive battery life (30 hours on a single charge with noise cancellation enabled and for 35 hours without it), it's the best of both worlds.
And now they've knocked £101 off the UK price, meaning you get top quality headphones for £139 (or 5 monthly payments of £25.80).
Sony Wh-XB900N headphones: were £230, now £139 at Amazon
Wireless, noise cancelling, comfortable, with a long battery life and exceptional audio performance – Sony has nailed it. As Techradar commented: "There aren't many headphones out there in the market that are able to provide this kind of listening experience." View Deal


The Von Neumann architecture is defined by the fact that both the machine instructions and data are stored in the same memory space. This fact necessitates dividing memory into text and data segments.
In the computer memory, the program is organized as follows :
Data segment consists of static and global variables that are explicitly initialized with values. This segment can be further broken down into ro-data (read only data), a read-only data segment, and rw-data (read write data), a read / write data segment. For example, global variables
s[] = "hello world";
int debug=1
Will be stored in the rw-area.
For an expression likeconst char* string = "hello world"
the pointer will be stored in the rw-area, and the string literal "hello world" in the ro-area.
static int i = 10;
int i = 10;
both will be located in the data segment.
begins behind the BSS segment and grows from there, correspondingly with an increase in the address. This section is used to allocate memory on it using the malloc function (and others) and to clear it using the free function.
usually grows "towards" the heap, that is, as the stack grows, the address of the top of the stack decreases. A set of values that are pushed onto the stack by one function is called a frame. After exiting the function, the stack is freed from the frame. One frame stores at least one value - the return address. Every time we create local variables, they are placed on the stack. As soon as we exit the function, the stack is cleared and the variables disappear. Function calls and parameters are also passed through the stack.
just text, contains executable instructions. It has a fixed size and is usually used only for reading, but if you can write to it, then the architecture supports self-modification. The code segment is located after the start of the stack, so if it grows, it [the stack] does not overlap the code segment.


Duration
Extends:
A time-based amount of time, such as '34.5 seconds'.
This class models a quantity or amount of time in terms of seconds and nanoseconds. It can be accessed using other duration-based units, such as minutes and hours. In addition, the ChronoUnit#DAYS unit can be used and is treated as exactly equal to 24 hours, thus ignoring daylight savings effects. See Period for the date-based equivalent to this class.
A physical duration could be of infinite length.
For practicality, the duration is stored with constraints similar to Instant.
The duration uses nanosecond resolution with a maximum value of the seconds that can
be held in a long
. This is greater than the current estimated age of the universe.
The range of a duration requires the storage of a number larger than a long
.
To achieve this, the class stores a long
representing seconds and an int
representing nanosecond-of-second, which will always be between 0 and 999,999,999.
The duration is measured in "seconds", but these are not necessarily identical to the scientific "SI second" definition based on atomic clocks. This difference only impacts durations measured near a leap-second and should not affect most applications. See Instant for a discussion as to the meaning of the second and time-scales.
Static properties of Class Duration
Duration.ZERO
Constant for a duration of zero.
Static Method Summary
| Static Public Methods | ||
| public static |
Obtains an instance of Duration representing the duration between two instants. |
|
| public static |
from(amount: TemporalAmount): Duration Obtains an instance of Duration from an amount. |
|
| public static |
of(amount: Number, unit: TemporalUnit): Duration Obtains an instance of Duration from a duration in the specified unit. |
|
| public static |
Obtains an instance of Duration from a number of standard 24 hour days. |
|
| public static |
Obtains an instance of Duration from a number of standard hours. |
|
| public static |
Obtains an instance of Duration from a number of milliseconds. |
|
| public static |
Obtains an instance of Duration from a number of standard minutes. |
|
| public static |
Obtains an instance of Duration from a number of nanoseconds. |
|
| public static |
Obtains an instance of Duration from a number of seconds and an adjustment in nanoseconds. |
|
| public static |
Obtains a Duration from a text string such as PnDTnHnMn.nS. |
Method Summary
| Public Methods | ||
| public |
Returns a copy of this duration with a positive length. |
|
| public |
Adds this duration to the specified temporal object. |
|
| public |
Compares this duration to the specified Duration. |
|
| public |
Returns a copy of this duration divided by the specified value. |
|
| public |
equals(otherDuration: *): boolean Checks if this duration is equal to the specified Duration. |
|
| public |
get(unit: TemporalUnit): number Gets the value of the requested unit. |
|
| public |
isNegative(): boolean Checks if this duration is negative, excluding zero. |
|
| public |
isZero(): boolean Checks if this duration is zero length. |
|
| public |
minus(durationOrNumber: Duration | number, unit: TemporalUnit): Duration function overloading for Duration.minus |
|
| public |
minusAmountUnit(amountToSubtract: Number, unit: TemporalUnit): Duration Returns a copy of this duration with the specified duration subtracted. |
|
| public |
Returns a copy of this duration with the specified duration in 24 hour days subtracted. |
|
| public |
minusDuration(duration: Duration): Duration Returns a copy of this duration with the specified duration subtracted. |
|
| public |
minusHours(hoursToSubtract: Number): Duration Returns a copy of this duration with the specified duration in hours subtracted. |
|
| public |
minusMillis(millisToSubtract: Number): Duration Returns a copy of this duration with the specified duration in milliseconds subtracted. |
|
| public |
minusMinutes(minutesToSubtract: Number): Duration Returns a copy of this duration with the specified duration in minutes subtracted. |
|
| public |
minusNanos(nanosToSubtract: Number): Duration Returns a copy of this duration with the specified duration in nanoseconds subtracted. |
|
| public |
minusSeconds(secondsToSubtract: Number): Duration Returns a copy of this duration with the specified duration in seconds subtracted. |
|
| public |
multipliedBy(multiplicand: Number): Duration Returns a copy of this duration multiplied by the scalar. |
|
| public |
nano(): number Gets the number of nanoseconds within the second in this duration. |
|
| public |
Returns a copy of this duration with the length negated. |
|
| public |
plus(durationOrNumber: Duration | number, unitOrNumber: TemporalUnit | number): Duration function overloading for Duration.plus |
|
| public |
plusAmountUnit(amountToAdd: Number, unit: TemporalUnit): Duration Returns a copy of this duration with the specified duration added. |
|
| public |
Returns a copy of this duration with the specified duration in 24 hour days added. |
|
| public |
plusDuration(duration: Duration): Duration Returns a copy of this duration with the specified duration added. |
|
| public |
Returns a copy of this duration with the specified duration in hours added. |
|
| public |
plusMillis(millisToAdd: Number): Duration Returns a copy of this duration with the specified duration in milliseconds added. |
|
| public |
plusMinutes(minutesToAdd: Number): Duration Returns a copy of this duration with the specified duration in minutes added. |
|
| public |
Returns a copy of this duration with the specified duration in nanoseconds added. |
|
| public |
plusSeconds(secondsToAdd: Number): Duration Returns a copy of this duration with the specified duration in seconds added. |
|
| public |
plusSecondsNanos(secondsToAdd: Number, nanosToAdd: Number): Duration Returns a copy of this duration with the specified duration added. |
|
| public |
seconds(): number Gets the number of seconds in this duration. |
|
| public |
subtractFrom(temporal: Temporal): Temporal Subtracts this duration from the specified temporal object. |
|
| public |
toDays(): number Gets the number of days in this duration. |
|
| public |
toHours(): number Gets the number of hours in this duration. |
|
| public |
toJSON(): string |
|
| public |
toMillis(): number Converts this duration to the total length in milliseconds. |
|
| public |
toMinutes(): number Gets the number of minutes in this duration. |
|
| public |
toNanos(): number Converts this duration to the total length in nanoseconds expressed as a |
|
| public |
toString(): string A string representation of this duration using ISO-8601 seconds based representation, such as PT8H6M12.345S. |
|
| public |
units(): undefined[] |
|
| public |
Returns a copy of this duration with the specified nano-of-second. |
|
| public |
withSeconds(seconds: Number): Duration Returns a copy of this duration with the specified amount of seconds. |
Inherited Summary
| From class TemporalAmount | ||
| public |
Adds to the specified temporal object. |
|
| public |
get(unit: TemporalUnit): number Returns the value of the requested unit. |
|
| public |
subtractFrom(temporal: Temporal): Temporal Subtracts this object from the specified temporal object. |
|
| public |
units(): TemporalUnit[] Returns the list of units uniquely defining the value of this TemporalAmount. |
Static Public Methods
public static between(startInclusive: Temporal, endExclusive: Temporal): Duration source
Obtains an instance of Duration representing the duration between two instants.
Obtains a Duration representing the duration between two instants. This calculates the duration between two temporal objects of the same type. The difference in seconds is calculated using Temporal#until. The difference in nanoseconds is calculated using by querying the ChronoField#NANO_OF_SECOND field.
The result of this method can be a negative period if the end is before the start. To guarantee to obtain a positive duration call abs() on the result.
Throw:
* |
DateTimeException if the seconds between the temporals cannot be obtained |
* |
ArithmeticException if the calculation exceeds the capacity of Duration |
public static from(amount: TemporalAmount): Duration source
Obtains an instance of Duration from an amount.
This obtains a duration based on the specified amount. A TemporalAmount represents an amount of time, which may be date-based or time-based, which this factory extracts to a duration.
The conversion loops around the set of units from the amount and uses the duration of the unit to calculate the total Duration. Only a subset of units are accepted by this method. The unit must either have an exact duration or be ChronoUnit.DAYS which is treated as 24 hours. If any other units are found then an exception is thrown.
Params:
| Name | Type | Attribute | Description |
| amount | TemporalAmount | the temporal amount to convert, not null |
Throw:
* |
DateTimeException if the amount cannot be converted |
* |
ArithmeticException if a numeric overflow occurs |
public static of(amount: Number, unit: TemporalUnit): Duration source
Obtains an instance of Duration from a duration in the specified unit.
The parameters represent the two parts of a phrase like '6 Hours'. For example:
Duration.of(3, SECONDS); Duration.of(465, HOURS);Only a subset of units are accepted by this method. The unit must either have an exact duration (see TemporalUnit#isDurationEstimated) or be ChronoUnit#DAYS which is treated as 24 hours. Other units throw an exception.
Params:
| Name | Type | Attribute | Description |
| amount | Number | the amount of the duration, measured in terms of the unit, positive or negative |
|
| unit | TemporalUnit | the unit that the duration is measured in, must have an exact duration, not null |
Throw:
* |
DateTimeException if the period unit has an estimated duration |
* |
ArithmeticException if a numeric overflow occurs |
public static ofDays(days: Number): Duration source
Obtains an instance of Duration from a number of standard 24 hour days.
The seconds are calculated based on the standard definition of a day, where each day is 86400 seconds which implies a 24 hour day. The nanosecond in second field is set to zero.
Params:
| Name | Type | Attribute | Description |
| days | Number | the number of days, positive or negative |
Throw:
* |
ArithmeticException if the input days exceeds the capacity of Duration |
public static ofHours(hours: Number): Duration source
Obtains an instance of Duration from a number of standard hours.
The seconds are calculated based on the standard definition of an hour, where each hour is 3600 seconds. The nanosecond in second field is set to zero.
Params:
| Name | Type | Attribute | Description |
| hours | Number | the number of hours, positive or negative |
Throw:
* |
ArithmeticException if the input hours exceeds the capacity of Duration |
public static ofMillis(millis: Number): Duration source
Obtains an instance of Duration from a number of milliseconds.
The seconds and nanoseconds are extracted from the specified milliseconds.
Params:
| Name | Type | Attribute | Description |
| millis | Number | the number of milliseconds, positive or negative |
public static ofMinutes(minutes: Number): Duration source
Obtains an instance of Duration from a number of standard minutes.
The seconds are calculated based on the standard definition of a minute, where each minute is 60 seconds. The nanosecond in second field is set to zero.
Params:
| Name | Type | Attribute | Description |
| minutes | Number | the number of minutes, positive or negative |
Throw:
* |
ArithmeticException if the input minutes exceeds the capacity of Duration |
public static ofNanos(nanos: Number): Duration source
Obtains an instance of Duration from a number of nanoseconds.
The seconds and nanoseconds are extracted from the specified nanoseconds.
Params:
| Name | Type | Attribute | Description |
| nanos | Number | the number of nanoseconds, positive or negative |
public static ofSeconds(seconds: Number, nanoAdjustment: Number): Duration source
Obtains an instance of Duration from a number of seconds and an adjustment in nanoseconds.
This method allows an arbitrary number of nanoseconds to be passed in. The factory will alter the values of the second and nanosecond in order to ensure that the stored nanosecond is in the range 0 to 999,999,999. For example, the following will result in the exactly the same duration:
Duration.ofSeconds(3, 1); Duration.ofSeconds(4, -999_999_999); Duration.ofSeconds(2, 1000_000_001);
Params:
| Name | Type | Attribute | Description |
| seconds | Number | the number of seconds, positive or negative |
|
| nanoAdjustment | Number | the nanosecond adjustment to the number of seconds, positive or negative |
Throw:
* |
ArithmeticException if the adjustment causes the seconds to exceed the capacity of Duration |
public static parse(text: String): Duration source
Obtains a Duration from a text string such as PnDTnHnMn.nS.
This will parse a textual representation of a duration, including the string produced by toString. The formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS with days considered to be exactly 24 hours.
The string starts with an optional sign, denoted by the ASCII negative
or positive symbol. If negative, the whole period is negated.
The ASCII letter "P" is next in upper or lower case.
There are then four sections, each consisting of a number and a suffix.
The sections have suffixes in ASCII of "D", "H", "M" and "S" for
days, hours, minutes and seconds, accepted in upper or lower case.
The suffixes must occur in order. The ASCII letter "T" must occur before
the first occurrence, if any, of an hour, minute or second section.
At least one of the four sections must be present, and if "T" is present
there must be at least one section after the "T".
The number part of each section must consist of one or more ASCII digits.
The number may be prefixed by the ASCII negative or positive symbol.
The number of days, hours and minutes must parse to a long
.
The number of seconds must parse to a long
with optional fraction.
The decimal point may be either a dot or a comma.
The fractional part may have from zero to 9 digits.
The leading plus/minus sign, and negative values for other units are not part of the ISO-8601 standard.
Examples:
"PT20.345S" -> parses as "20.345 seconds" "PT15M" -> parses as "15 minutes" (where a minute is 60 seconds) "PT10H" -> parses as "10 hours" (where an hour is 3600 seconds) "P2D" -> parses as "2 days" (where a day is 24 hours or 86400 seconds) "P2DT3H4M" -> parses as "2 days, 3 hours and 4 minutes" "P-6H3M" -> parses as "-6 hours and +3 minutes" "-P6H3M" -> parses as "-6 hours and -3 minutes" "-P-6H+3M" -> parses as "+6 hours and -3 minutes"
Params:
| Name | Type | Attribute | Description |
| text | String | the text to parse, not null |
Throw:
* |
DateTimeParseException if the text cannot be parsed to a duration |
Public Methods
public abs(): Duration source
Returns a copy of this duration with a positive length.
This method returns a positive duration by effectively removing the sign from any negative total length. For example, PT-1.3S will be returned as PT1.3S.
This instance is immutable and unaffected by this method call.
Throw:
* |
ArithmeticException if numeric overflow occurs |
public addTo(temporal: Temporal): Temporal source
Adds this duration to the specified temporal object.
This returns a temporal object of the same observable type as the input with this duration added.
In most cases, it is clearer to reverse the calling pattern by using Temporal#plus.
// these two lines are equivalent, but the second approach is recommended dateTime = thisDuration.addTo(dateTime); dateTime = dateTime.plus(thisDuration);
The calculation will add the seconds, then nanos. Only non-zero amounts will be added.
This instance is immutable and unaffected by this method call.
Override:
TemporalAmount#addToParams:
| Name | Type | Attribute | Description |
| temporal | Temporal | the temporal object to adjust, not null |
Throw:
* |
DateTimeException if unable to add |
* |
ArithmeticException if numeric overflow occurs |
public compareTo(otherDuration: Duration): number source
Compares this duration to the specified Duration.
The comparison is based on the total length of the durations.
Params:
| Name | Type | Attribute | Description |
| otherDuration | Duration | the other duration to compare to, not null |
Return:
| number | the comparator value, negative if less, positive if greater |
public dividedBy(divisor: Number): Duration source
Returns a copy of this duration divided by the specified value.
In opposite to the threeten implementation the division is realized by floating point not by fixed point arithmetic. Expect floating point rounding errors for Duration.dividedBy.
Params:
| Name | Type | Attribute | Description |
| divisor | Number | the value to divide the duration by, positive or negative, not zero |
Throw:
* |
ArithmeticException if the divisor is zero or if numeric overflow occurs |
public equals(otherDuration: *): boolean source
Checks if this duration is equal to the specified Duration.
The comparison is based on the total length of the durations.
Params:
| Name | Type | Attribute | Description |
| otherDuration | * | the other duration, null returns false |
Return:
| boolean | true if the other duration is equal to this one |
public get(unit: TemporalUnit): number source
Gets the value of the requested unit.
This returns a value for each of the two supported units, ChronoUnit#SECONDS and ChronoUnit#NANOS. All other units throw an exception.
Override:
TemporalAmount#getParams:
| Name | Type | Attribute | Description |
| unit | TemporalUnit | the TemporalUnit for which to return the value |
Return:
| number | the const value of the unit |
Throw:
* |
DateTimeException if the unit is not supported |
* |
UnsupportedTemporalTypeException if the unit is not supported |
public isNegative(): boolean source
Checks if this duration is negative, excluding zero.
A Duration represents a directed distance between two points on the time-line and can therefore be positive, zero or negative. This method checks whether the length is less than zero.
Return:
| boolean | true if this duration has a total length less than zero |
public isZero(): boolean source
Checks if this duration is zero length.
A Duration represents a directed distance between two points on the time-line and can therefore be positive, zero or negative. This method checks whether the length is zero.
Return:
| boolean | true if this duration has a total length equal to zero |
public minus(durationOrNumber: Duration | number, unit: TemporalUnit): Duration source
function overloading for Duration.minus
if called with 1 arguments and first argument is an instance of Duration, then Duration.minusDuration is executed.
Otherwise Duration.minusAmountUnit is executed.
Params:
| Name | Type | Attribute | Description |
| durationOrNumber | Duration | number |
|
|
| unit | TemporalUnit |
|
public minusAmountUnit(amountToSubtract: Number, unit: TemporalUnit): Duration source
Returns a copy of this duration with the specified duration subtracted.
The duration amount is measured in terms of the specified unit. Only a subset of units are accepted by this method. The unit must either have an exact duration (see TemporalUnit#isDurationEstimated) or be ChronoUnit#DAYS which is treated as 24 hours. Other units throw an exception.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| amountToSubtract | Number | the amount to subtract, measured in terms of the unit, positive or negative |
|
| unit | TemporalUnit | the unit that the amount is measured in, must have an exact duration, not null |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusDays(daysToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in 24 hour days subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| daysToSubtract | Number | the days to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusDuration(duration: Duration): Duration source
Returns a copy of this duration with the specified duration subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| duration | Duration | the duration to subtract, positive or negative, not null |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusHours(hoursToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in hours subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| hoursToSubtract | Number | the hours to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusMillis(millisToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in milliseconds subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| millisToSubtract | Number | the milliseconds to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusMinutes(minutesToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in minutes subtracted.
The number of hours is multiplied by 60 to obtain the number of seconds to subtract.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| minutesToSubtract | Number | the minutes to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusNanos(nanosToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in nanoseconds subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| nanosToSubtract | Number | the nanoseconds to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public minusSeconds(secondsToSubtract: Number): Duration source
Returns a copy of this duration with the specified duration in seconds subtracted.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| secondsToSubtract | Number | the seconds to subtract, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public multipliedBy(multiplicand: Number): Duration source
Returns a copy of this duration multiplied by the scalar.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| multiplicand | Number | the value to multiply the duration by, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public nano(): number source
Gets the number of nanoseconds within the second in this duration.
The length of the duration is stored using two fields - seconds and nanoseconds. The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to the length in seconds. The total duration is defined by calling this method and getSeconds.
A Duration represents a directed distance between two points on the time-line. A negative duration is expressed by the negative sign of the seconds part. A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
Return:
| number | the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999 |
public negated(): Duration source
Returns a copy of this duration with the length negated.
This method swaps the sign of the total length of this duration. For example, PT1.3S will be returned as PT-1.3S.
This instance is immutable and unaffected by this method call.
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plus(durationOrNumber: Duration | number, unitOrNumber: TemporalUnit | number): Duration source
function overloading for Duration.plus
if called with 1 arguments, then Duration.plusDuration is executed.
if called with 2 arguments and second argument is an instance of TemporalUnit, then Duration.plusAmountUnit is executed.
Otherwise Duration.plusSecondsNanos is executed.
Params:
| Name | Type | Attribute | Description |
| durationOrNumber | Duration | number |
|
|
| unitOrNumber | TemporalUnit | number |
|
public plusAmountUnit(amountToAdd: Number, unit: TemporalUnit): Duration source
Returns a copy of this duration with the specified duration added.
The duration amount is measured in terms of the specified unit. Only a subset of units are accepted by this method. The unit must either have an exact duration (see TemporalUnit#isDurationEstimated) or be ChronoUnit#DAYS which is treated as 24 hours. Other units throw an exception.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| amountToAdd | Number | the amount to add, measured in terms of the unit, positive or negative |
|
| unit | TemporalUnit | the unit that the amount is measured in, must have an exact duration, not null |
Throw:
* |
UnsupportedTemporalTypeException if the unit is not supported |
* |
ArithmeticException if numeric overflow occurs |
public plusDays(daysToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in 24 hour days added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| daysToAdd | Number | the days to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusDuration(duration: Duration): Duration source
Returns a copy of this duration with the specified duration added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| duration | Duration | the duration to add, positive or negative, not null |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusHours(hoursToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in hours added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| hoursToAdd | Number | the hours to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusMillis(millisToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in milliseconds added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| millisToAdd | Number | the milliseconds to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusMinutes(minutesToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in minutes added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| minutesToAdd | Number | the minutes to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusNanos(nanosToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in nanoseconds added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| nanosToAdd | Number | the nanoseconds to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusSeconds(secondsToAdd: Number): Duration source
Returns a copy of this duration with the specified duration in seconds added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| secondsToAdd | Number | the seconds to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public plusSecondsNanos(secondsToAdd: Number, nanosToAdd: Number): Duration source
Returns a copy of this duration with the specified duration added.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| secondsToAdd | Number | the seconds to add, positive or negative |
|
| nanosToAdd | Number | the nanos to add, positive or negative |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public seconds(): number source
Gets the number of seconds in this duration.
The length of the duration is stored using two fields - seconds and nanoseconds. The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to the length in seconds. The total duration is defined by calling this method and getNano.
A Duration represents a directed distance between two points on the time-line. A negative duration is expressed by the negative sign of the seconds part. A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.
Return:
| number | the whole seconds part of the length of the duration, positive or negative |
public subtractFrom(temporal: Temporal): Temporal source
Subtracts this duration from the specified temporal object.
This returns a temporal object of the same observable type as the input with this duration subtracted.
In most cases, it is clearer to reverse the calling pattern by using Temporal#minus.
// these two lines are equivalent, but the second approach is recommended dateTime = thisDuration.subtractFrom(dateTime); dateTime = dateTime.minus(thisDuration);
The calculation will subtract the seconds, then nanos. Only non-zero amounts will be added.
This instance is immutable and unaffected by this method call.
Override:
TemporalAmount#subtractFromParams:
| Name | Type | Attribute | Description |
| temporal | Temporal | the temporal object to adjust, not null |
Throw:
* |
DateTimeException if unable to subtract |
* |
ArithmeticException if numeric overflow occurs |
public toDays(): number source
Gets the number of days in this duration.
This returns the total number of days in the duration by dividing the number of seconds by 86400. This is based on the standard definition of a day as 24 hours.
This instance is immutable and unaffected by this method call.
Return:
| number | the number of days in the duration, may be negative |
public toHours(): number source
Gets the number of hours in this duration.
This returns the total number of hours in the duration by dividing the number of seconds by 3600.
This instance is immutable and unaffected by this method call.
Return:
| number | the number of hours in the duration, may be negative |
public toMillis(): number source
Converts this duration to the total length in milliseconds.
If this duration is too large to fit in a long
milliseconds, then an
exception is thrown.
If this duration has greater than millisecond precision, then the conversion will drop any excess precision information as though the amount in nanoseconds was subject to integer division by one million.
Return:
| number | the total length of the duration in milliseconds |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public toMinutes(): number source
Gets the number of minutes in this duration.
This returns the total number of minutes in the duration by dividing the number of seconds by 60.
This instance is immutable and unaffected by this method call.
Return:
| number | the number of minutes in the duration, may be negative |
public toNanos(): number source
Converts this duration to the total length in nanoseconds expressed as a long
.
If this duration is too large to fit in a long
nanoseconds, then an
exception is thrown.
Return:
| number | the total length of the duration in nanoseconds |
Throw:
* |
ArithmeticException if numeric overflow occurs |
public toString(): string source
A string representation of this duration using ISO-8601 seconds based representation, such as PT8H6M12.345S.
The format of the returned string will be PTnHnMnS, where n is the relevant hours, minutes or seconds part of the duration. Any fractional seconds are placed after a decimal point in the seconds section. If a section has a zero value, it is omitted. The hours, minutes and seconds will all have the same sign.
Examples:
"20.345 seconds" -> "PT20.345S "15 minutes" (15 60 seconds) -> "PT15M" "10 hours" (10 3600 seconds) -> "PT10H" "2 days" (2 * 86400 seconds) -> "PT48H"Note that multiples of 24 hours are not output as days to avoid confusion with Period.
Return:
| string | an ISO-8601 representation of this duration, not null |
public units(): undefined[] source
Returns the list of units uniquely defining the value of this TemporalAmount. The list of TemporalUnits is defined by the implementation class. The list is a snapshot of the units at the time getUnits is called and is not mutable. The units are ordered from longest duration to the shortest duration of the unit.
Override:
TemporalAmount#unitsReturn:
| undefined[] |
public withNanos(nanoOfSecond: Number): Duration source
Returns a copy of this duration with the specified nano-of-second.
This returns a duration with the specified nano-of-second, retaining the seconds part of this duration.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| nanoOfSecond | Number | the nano-of-second to represent, from 0 to 999,999,999 |
Throw:
* |
DateTimeException if the nano-of-second is invalid |
public withSeconds(seconds: Number): Duration source
Returns a copy of this duration with the specified amount of seconds.
This returns a duration with the specified seconds, retaining the nano-of-second part of this duration.
This instance is immutable and unaffected by this method call.
Params:
| Name | Type | Attribute | Description |
| seconds | Number | the seconds to represent, may be negative |


Duino-Coin Web Wallet
Sign up
Create a new Duino-Coin Wallet
The username will also be your wallet address. It can consist of alphanumeric characters, numbers and underscores or dashes.
Choose a strong password and save it in a safe place. There is no way to recover it if it gets lost because we don't store them for security reasons.
Please provide a real e-mail as it will be used to confirm exchanges and receive updates about your account.
By registering you agree to the Duino-Coin terms of usage and privacy policy
Official Duino-Coin Web Wallet ©
revox ·
Yennefer ·
LDarki
Hosted by
Kristian
and
GH Pages
·
MIT licensed
This page is open source. You can improve it
here
Error
Success


MongoDB query language for in-memory objects
$ npm install mingo
<array>.<index>
and <document>.<field>
selectorsmingo.addOperators
For documentation on using query operators see mongodb
// Use as es6 module
import mingo from 'mingo'
// or vanilla nodeJS
const mingo = require('mingo')
The $where
operator is not loaded by default and must be explicitly registered if required. See documentation for preferred alternatives.
The default export of the main module only includes Aggregator
, Query
, aggregate()
, find()
, and remove()
.
Only Query and Projection operators are loaded by default when using the main module.
This is done using the side-effect module mingo/init/basic
, and also automatically includes pipeline operators $project
, $skip
, $limit
, and $sort
.
If your application uses most of the available operators or you do not care about bundle size, you can load all operators as shown below.
// Note that doing this effectively imports the entire library into your bundle and unused operators cannot be tree shaked
import 'mingo/init/system'
Or from the node CLI
node -r 'mingo/init/system' myscript.js
The addOperators
function for registering custom operators and helper constants have been moved to mingo/core
.
The constants OP_XXX
have been deprecated and replace with an enum type OperatorType
also in mingo/core
.
The values defined include;
ACCUMULATOR
EXPRESSION
PIPELINE
PROJECTION
QUERY
Lastly, the function argument to addOperators(operatorType, fn)
now accepts an object with the these two internal functions;
computeValue(obj: object | any[], expr: any, operator: string, options?: ComputeOptions): any
resolve(obj: object | any[], selector: string, options?: ResolveOptions): any
Any extra utility may be imported directly from the specific module.
Submodule imports are supported for both ES6 and ES5.
The following two examples are equivalent.
This work natively in typescript since it knows how to load commonJS modules as ES6. You may optionally install the esm module to use this syntax.
import { $unwind } from 'mingo/operators/pipeline'
Unlike the ES6 version, it is necessary to specify the operator module in the path to avoid loading any extras
const $unwind = require('mingo/operators/pipeline/unwind').$unwind
To support tree-shaking, you may import and register specific operators that will be used in your application.
import { useOperators, OperatorType } from 'mingo/core'
import { $trunc } from 'mingo/operators/expression'
import { $bucket } from 'mingo/operators/pipeline'
useOperators(OperatorType.EXPRESSION, { $trunc, $floor })
useOperators(OperatorType.PIPELINE, { $bucket })
import mingo from 'mingo'
// create a query with criteria
// find all grades for homework with score >= 50
let query = new mingo.Query({
type: "homework",
score: { $gte: 50 }
});
// test if an object matches query
query.test(doc)
import mingo from 'mingo'
// input is either an Array or any iterable source (i.e Object{next:Function}) including ES6 generators.
let criteria = { score: { $gt: 10 } }
let query = new mingo.Query(criteria)
// filter collection with find()
let cursor = query.find(collection)
// alternatively use shorthand
// cursor = mingo.find(collection, criteria)
// sort, skip and limit by chaining
cursor.sort({student_id: 1, score: -1})
.skip(100)
.limit(100)
// count matches. exhausts cursor
cursor.count()
// classic cursor iterator (old school)
while (cursor.hasNext()) {
console.log(cursor.next())
}
// ES6 iterators (new cool)
for (let value of cursor) {
console.log(value)
}
// all() to retrieve matched objects. exhausts cursor
cursor.all()
import { Aggregator } from 'mingo/aggregator'
import { useOperators, OperatorType } from 'mingo/core'
import { $match, $group } from 'mingo/operators/pipeline'
import { $min } from 'mingo/operators/accumulator'
// ensure the required operators are preloaded prior to using them.
useOperators(OperatorType.PIPELINE, { $match, $group })
useOperators(OperatorType.ACCUMULATOR, { $min })
let agg = new Aggregator([
{'$match': { "type": "homework"}},
{'$group': {'_id':'$student_id', 'score':{$min:'$score'}}},
{'$sort': {'_id': 1, 'score': 1}}
])
// return an iterator for streaming results
let stream = agg.stream(collection)
// return all results. same as `stream.all()`
let result = agg.run(collection)
npm test
to build and execute unit testsMIT
Generated using TypeDoc


Google will help you pronounce difficult words
A new Search feature uses advanced speech recognition and machine learning to offer feedback.
by Christine FisherGoogle wants to make it easier to learn word pronunciations. Today, it introduced a new Search feature that will let users practice saying tricky words. When you look up a pronunciation, Google will provide an answer, and when you say the word into your phone's microphone, Search will let you know if you said it correctly.
According to Google, the feature uses speech recognition technology to break spoken words into individual soundbites. Then, it uses machine learning to tell if your pronunciation was correct, and it offers syllable-specific feedback. This feature rolls out in American English today, and a Spanish version will soon follow.
Google is also adding images to dictionary definitions. It will start with English nouns -- like seal and avocado. It will eventually expand to all language translations.


A Keyman keyboard for the Vai language of Liberia, developed by the team at Athinkra, LLC. This keyboard uses fewer keystrokes than the "Vai (Athinkra)" keyboard and is more ergonomic.
Because there are so many characters in the Vai script, this keyboard requires multiple keystrokes to access most of the characters.
Vowel marks and nasilized vowels are on the corresponding vowel keys.
To type a consonant, you must type the consonant first, and then the vowel. For example:
The hyphen characters on the RIGHT ALT layer are used for accessing historic syllables. Type the character followed by a vowel and the historic syllable will be formed. There are not historic syllables for every vowel, so the hyphen may remain in the text unexpectedly).
(c) 2008-2020 Athinkra, LLC


1
#517: Dr. Peter Attia on Longevity Drugs, Alzheimer's Disease, and the 3 Most Important Levers to Pull
2
#509: George Mumford, Mindfulness Coach to Michael Jordan and Kobe Bryant, on Awareness, Compassionate Action, The Dizziness of Freedom, and More
3
#504: Vitalik Buterin, Creator of Ethereum, on Understanding Ethereum, ETH vs. BTC, ETH2, Scaling Plans and Timelines, NFTs, Future Considerations, Life Extension, and More (Featuring Naval Ravikant)