Improve Git Monorepo Performance

Today, I was exploring source code of the Gitlab project and experienced poor performance of the git status command. Gitlab is an open source alternative to Github.

Below is the output of git status command

 time git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
git status  0.20s user 1.13s system 88% cpu 1.502 total

The total here is the number of seconds it took for the command to complete.

The same was the case for the git add command.

time git add .
git add .  0.21s user 1.11s system 115% cpu 1.146 total

So both commands took more than a second to finish.

These commands are slow because they need to search the entire worktree looking for changes. When the worktree is very large, Git needs to do a lot of work.

Continue reading “Improve Git Monorepo Performance”

Linux Tip: How to create a list of directories inside a directory and place an empty file in each of them

Today, I wanted to create a list of directories inside a directory and place an empty file in each of them. In this quick post, I will share two commands that can do that for you.

$ mkdir $(printf "%02i-day " $(seq 1 50))
$ find . -type d -exec touch {}/.gitkeep \;

You don’t have to type $. It is only to signify command-prompt.

Eclipse Memory Analyzer: Solution to Use the -data parameter Exception

If you launch Eclipse MAT and get following error

java.lang.IllegalStateException: The platform metadata area could not be written: /private/var/folders/9q/zhpkyd3s4y9d5t1nv_5hszww0000gp/T/AppTranslocation/DF264CA5-4EEF-4916-A3FA-881B111294E5/d/mat.app/Contents/MacOS/work/.metadata.  By default the platform writes its content
under the current working directory when the platform is launched.  Use the -data parameter to
specify a different content area for the platform.

Then you should open the MemoryAnalyzer.ini in your favorite editor and add the -data argument as shown below.

The location of MemoryAnalyzer.ini depends on your platform. If you are using Mac, then it is inside the app folder like mat.app/Contents/Eclipse/MemoryAnalyzer.ini

-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
-data
/Users/shekhargulati/dev/tmp/mat
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.700.v20180518-1200
-vmargs
-Xmx4096m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread

Solution: ORA-12514, TNS:listener does not currently know of service requested in connect descriptor

Today, one of the teams was facing the issue ORA-12514, TNS:listener does not currently know of service requested in connect descriptor. They were trying to connect to Oracle using Spring Boot JPA application and getting the exception at application boot up.

Team was able to successfully connect to Oracle using SQLDeveloper. But, when connecting to Oracle using Spring Boot JPA application it was failing to boot up.

Like most developers, we googled around to find the answers. The popular answer that you will get is as mentioned in this stackoverflow question. The answer suggests that you have to update tnsnames.ora file and add your service to it.

I knew it is not the right answer as we are able to connect using SQL Developer.

So, I started looking into the Spring Data JPA configuration of the application. The configuration that was giving error is shown below.

spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@//myhost:1521/efsdev
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect

In the above configuration, there is only one configuration property that could be possibly wrong — spring.datasource.url.

So, I googled around to find the correct way to specify JDBC url for Oracle.

I learned that there are two ways you can specify JDBC string URL. The two ways are:

1) jdbc:oracle:thin:@[HOST][:PORT]:SID

2) jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE

As you can see above, we are using the second way to specify the URL. According to second URL syntax, efsdev is the service name.

Developers mentioned that efsdev is the SID. So, we need to use the first URL.

After changing the configuration to the one mentioned below, application was successfully able to connect with Oracle.

spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@myhost:1521:efsdev
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect

That’s it for this post. I hope this saves someone’s day.

How to Rename and Change Boolean column to Integer in PostgreSQL

Today, I faced a situation where I had to change a column type from Boolean to Integer. Also, I wanted to rename the column. Let’s suppose, we have tasks table that has a boolean column done. I want to rename done to status and change all false values to 0 and all true values to 1. To do that, you have to run following SQL query using PostgreSQL client.

ALTER TABLE tasks ALTER done SET DEFAULT null;
ALTER TABLE tasks
ALTER done TYPE INTEGER
USING
CASE
WHEN f THEN 0 ELSE 1
END;
ALTER TABLE tasks RENAME done TO status;

GSON tip: Setting ISO 8601 Date Time format with nano second precision

Today, I had to parse an ISO 8601 date that was returned as part of a JSON response from a REST service. With default settings GSON can’t parse the date like 2015-09-22T17:21:32.70856998Z. To make it work, use the code shown below.

Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
                .setPrettyPrinting()
                .create();