Using NPM ShrinkWrap to Lock Sub-dependency Versions

There may be times you want to restrict your package dependency versions for various reasons. NPM ShrinkWrap is used for this purpose, and it’s especially helpful when you need to control the versions of nested packages.

The usage is pretty straightforward. All you need is to create a npm-shrinkwrap.json and specify the versions inside. Then the second time you run npm install command, it will become replacement of your package-lock.json and get you the right package as you specified.

Let’s start with an example, I got this warning after merging a pull request for my current project from GitHub.

screen-shot-2018-02-14-at-5-52-33-pm-e1518660586168

It suggests to update one of my dependency or it might be vulnerable.

But I have no clue where this dependency is. Let’s try to locate the package by running npm list marked (notice you will need to run npm i first to get you node_modules):

Screen Shot 2018-02-14 at 8.07.07 PM

Great! Found it under textract – one of the dependencies in my package.json. 

Next is to have shrinkwrap downloaded.

npm install shrinkwrap --save

Now, create a npm-shrinkwrap.json and put the following:


{
"dependencies": {
"textract": {
"version": "2.2.0",
"dependencies": {
"marked": {
"version": "0.3.9"
}
}
}
}
}

Reinstall npm package and reissue npm list marked:

Screen Shot 2018-02-14 at 8.23.04 PM

Done! Successfully overwrite the version of textract sub-package.

Working with Cascade Delete in Entity Framework

Recently my group and I are working on a .NET Web API project. At some points after defining our design models, view models and the mappings, the Entity Framework didn’t create the local database for us.

When we enabled migrations and tried to run Update-Database on Package Manager Console, this error generated:

Screen Shot 2018-02-11 at 8.19.51 PM

It complains about the foreign key constraint on table Resident will cause cascade delete, which means if the table City got deleted, then the foreign key on table Resident will set to null.

Cascade delete is enabled by default in Entity Framework for all types of relationships such as one-to-one, one-to-many and many-to-many.

If you take a look at the migration test file, which generated by the Add-Migration Test command, you will notice when creating the foreign key “CityId” for table Resident, the cascade delete is turned on by default.

Screen Shot 2018-02-12 at 1.16.11 AM

In order to create our tables, we could configure Fluent API to turn off the cascade delete. But first, let’s take a look at our design models:

City.cs


namespace CascadeDelete.Models
{
public class City
{
public City()
{
Owners = new List<ResidentCityOwn>();
Residents = new List<Resident>();
}
public int Id { get; set; }
[Required]
[StringLength(40)]
public string Name { get; set; }
// navigations
public virtual ICollection<ResidentCityOwn> Owners { get; set; }
public virtual ICollection<Resident> Residents { get; set; }
}
}

view raw

City.cs

hosted with ❤ by GitHub

ResidentCityOwn.cs


namespace CascadeDelete.Models
{
public class ResidentCityOwn
{
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Title { get; set; }
[Required]
public int ResidentId { get; set; }
[Required]
public int CityId { get; set; }
// navigation props
public virtual Resident Resident { get; set; }
public virtual City City { get; set; }
}
}

Resident.cs


namespace CascadeDelete.Models
{
public class Resident
{
public Resident()
{
ResidentCityOwns = new List<ResidentCityOwn>();
}
public int Id { get; set; }
public String Name { get; set; }
[Required]
public int CityId { get; set; }
// navigation props
public virtual City City { get; set; }
public virtual ICollection<ResidentCityOwn> ResidentCityOwns { get; set; }
}
}

view raw

Resident.cs

hosted with ❤ by GitHub

Because the error is pointing to the Resident class, so we just focus on City and Resident for now. Note the City has a collection of Residents, so they are one-to-many.

Now put the configuration in DataContext.cs:


namespace CascadeDelete.Models
{
public class DataContext: DbContext
{
public virtual DbSet<Resident> Residents { get; set; }
public virtual DbSet<City> Cities { get; set; }
public virtual DbSet<ResidentCityOwn> ResidentCityOwn { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Fluent API configurations
modelBuilder.Entity<Resident>()
.HasRequired(e => e.City)
.WithMany(e => e.Residents)
.WillCascadeOnDelete(false);
}
}
}

view raw

DataContext.cs

hosted with ❤ by GitHub

Delete the previous migration file and start over, now you should see the following:

Screen Shot 2018-02-12 at 1.13.38 AM

Run the Update-Database command, and the database file should be generated:

Screen Shot 2018-02-12 at 1.27.15 AM

Sum up:

You probably not see the cascade delete very often. But sometimes based on your business logic, you want to configure your models to get rid of this default behavior, remember Fluent API is your friend🙌🙌.

Using SQLPlus on MacOS

Once you have the client installed, go ahead and create tnsnames.ora for your server connection under '/Applications/oracle/product/instantclient_64/network/admin'


ORACLE12C =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = myoracle12c.senecacollege.ca)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = oracle12c)
)
)

view raw

tnsnames.ora

hosted with ❤ by GitHub

Modify your .bash_profile to store environment variables:


export ORACLE_HOME="/Applications/oracle/product/instantclient_64"
export PATH=$ORACLE_HOME/bin:$PATH
export DYLD_LIBRARY_PATH=$ORACLE_HOME/lib
# Set ORACLE_PATH to the location where you store your custom "login.sql"
export ORACLE_PATH="/Applications/oracle/product/instantclient_64/sqlplus/admin"
alias sqlplus='rlwrap sqlplus'

view raw

.bash_profile

hosted with ❤ by GitHub

Then you can create your own startup script, e.g.


SET PAGESIZE 100;
SET LINESIZE 100;
define_editor='vi';
SET SERVEROUTPUT ON;
SET VERIFY OFF;

view raw

login.sql

hosted with ❤ by GitHub

Last, add the following command to your .bashrc to skip error command not found: sqlplus


# Add it to the end of your .bashrc as start-up command
source ~/.bash_profile

view raw

.bashrc

hosted with ❤ by GitHub

Note:
If you face Error ORA-21561: OID generation failed when connecting to Oracle with a Mac, edit your hosts file to append local computer name to the end of the 127.0.0.1 line.


##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost <local_computer_name>
255.255.255.255 broadcasthost

view raw

hosts

hosted with ❤ by GitHub

😌