Sunday, January 8, 2017

Bash | Learning Bash/Shell Scripting The Hard Way

Meskipun saya sudah menggunakan Sistem Operasi berbasis Linux sejak lebih dari 8 tahun lalu.
Cukup jarang saya harus berkutat dengan bash/shell scripting/programming, saya hanya sekedar tahu dan tidak pernah belajar lebih dalam.

Tapi karena tuntutan profesi (*haha profesi jare), mau tidak mau saya harus sedikit belajar, dengan bekal script warisan dari SysAdmin sebelumnya.

Langsung saja studi kasusnya adalah membuat bash script untuk melakukan proses backup database sistem (kami menggunakan PostgreSQL)  ke layanan Google Drive (berikutnya kita sebut gdrive). Kami mempunyai beberapa database server dan beberapa diantaranya dibatasi hanya bisa diakses dan mengakses via jaringan lokal (private network).

Untuk keperluan komunikasi dengan Google Drive via terminal, saya menggunakan tool bernama drive yang merupakan project open source dan bisa diakses via https://github.com/odeke-em/drive.

Gambaran untuk prosesnya adalah seperti ini:
Di node backup masih ada file backup yang lama untuk keperluan menghapusnya dari gdrive dan menggantinya dengan file backup baru. Lalu proses backup dilakukan, sehingga akan ada file backup baru dan backup lama di dalam satu folder. Langkah selanjutnya adalah menghapus file backup lama dari gdrive kemudian mengupload file backup yang baru. File backup yang lama kemudian dihapus dari node backup. Dan yang terakhir, untuk menghemat space di node backup, content file backup yang baru akan direset, sebab proses delete dari gdrive kita cukup mengetahui nama filenya saja.  


Berikut detail langkah yang saya lakukan
  1. Buat bash script di node yang bertugas untuk menjalankan backup (berikutnya kita sebut node backup), tentunya merupakan node yang bisa mengakses internet untuk keperluan upload ke gdrive
    • backup database postgres dan lakukan kompresi untuk menghemat space (di node backup maupun di gdrive nantinya) dan meringankan proses transfer dari node database ke node backup (meskipun proses ini melalui private network yang tentu jauh lebih cepat dibanding via internet). Perintahnya mudah, tinggal pipe hasil pg_dump ke gzip

      pg_dump -U[user] [nama database] | gzip > $nama_file
    • selanjutnya adalah melakukan file transfer dari node database (karena nantinya proses backup terjadi di node database bukan di node backup, dan karena saya tidak ingin melakukan backup langsung via jaringan *opsi -h [host database]). Saya menggunakan ftp untuk proses transfernya. Perintahnya adalah

      ftp -n -v $HOST_NODE_BACKUP << EOT
      ascii
      user $USERNAME $PASSWORD
      prompt
      # lakukan perintah ftp di sini
      quit
      EOT
  2. Seperti yang saya tulis di langkah ke-1, bahwa script backup ditulis di node backup, namun akan dijalankan di node database, untuk itu kita bisa menulis perintah

    cat script_backup_database.sh | ssh [user@node_database]
  3. Strateginya adalah saya ingin menghapus file backup yang lama dari gdrive dan menggantinya dengan file backup yang baru. Untuk keperluan (drive delete) ini saya perlu tahu nama file backup sebelumnya. Saya mengambil langkah untuk tetap menyimpan file backup yang sudah diupload ke gdrive di node backup, hanya saja saya juga tidak ingin memenuhi space di node backup. Saya hanya perlu tahu nama filenya saja. Jadi ketika proses upload selesai saya mereset content dari file backup dengan perintah

    cat /dev/null > $nama_file_backup*perintah ini ditulis di baris paling akhir dalam script nantinya

    dengan begitu nantinya saya bisa menghapus file dari gdrive dengan perintah

    drive delete -quiet $nama_file_backup_lama 
    *pakai opsi -quiet agar tidak ada prompt Yes/No sebelum menjalan proses aka forcing the process.


    Ketika proses backup database selesai (sebelum diupload ke gdrive), file backup baru maupun file backup lama masih tetap ada di node backup. Jadi ketika harus melakukan proses upload untuk file baru saja dengan perintah

    ls -t [filter file] | head -n 2 | xargs drive push -quiet -destination [folder di gdrive] 2>/dev/null
    *di sini kita bisa belajar kehebatan proses piping (meneruskan output perintah sebelumnya sebagai input ke proses setelahnya) di bash/shell
    • ls -t berfungsi untuk menampilkan list file berurutan mulai dari file terbaru di posisi teratas, tambah filter file yang ingin dilist jika perlu
    • head -n 2 bertugas untuk mengambil n file teratas, dalam kasus ini saya mengambil 2 file teratas (file backup yang terbaru)
    • xargs berfungsi untuk menampung output sebagai argument untuk perintah setelahnya, dalam hal ini,
    • drive push -quiet yang berfungsi untuk mengupload file ke gdrive, dalam kasus ini adalah file yang masuk ke xargs. Opsi -destination bisa kita tambahkan jika ingin file diupload ke folder tertentu, bukan pada folder root dari gdrive. Opsi -quiet sama fungsinya dengan sample drive delete.
    • 2>/dev/null berfungsi untuk meredirect error output ke /dev/null
  4. Setelahnya adalah menghapus file backup yang lama, karena sudah tidak diperlukan lagi. Sebab ketika script dijalankan lagi nantinya, file backup yang baru saja diupload akan berubah statusnya menjadi "file backup lama". Perintah yang dijalankan adalah

    ls -t [filter file] | tail -n +3 | xargs rm 2>/dev/null
    • tail -n +3 adalah kebalikan dari perintah head, yang mengambil n file terbawah, jika ditambahkan opsi +, berarti file terbawah yang diambil dimulai dari index ke-3. Sesuai dengan langkah sebelumnya, file backup terbaru adalah 2 file teratas
    • rm sudah tentunya untuk menghapus file yang ditampung oleh xargs
  5. Terakhir adalah reset content file backup baru dengan perintah yang sudah saya sebutkan di awal langkah ke-3
  6. Tambahan, script backup belum masuk dalam cronjob, maka saya harus mengeksekusi script tersebut secara manual. Namun karena koneksi saya tidak stabil dan tidak mau jika nantinya proses backup tidak bisa terpantau jika koneksi saya putus, maka opsi yang ada adalah mengeksekusi bash script ke background proses. Perintahnya adalah

    nohup file_bash_script.sh &

    Jadi meskipun koneksi bash/terminal saya putus atau saya logout dari bash sekalipun, proses backup akan tetap berjalan. Sehingga ketika login kembali, saya masih bisa memantau proses backup. 


Semoga bermanfaat
Then it's time to take good sleep now ^_^!

TODO:
  1. Memasukan file script ke cronjob
  2. Menambahkan strategi checksum agar kita bisa melakukan kroscek apakah file yang terupload di gdrive sudah valid atau belum

Wednesday, December 14, 2016

PostgreSQL | Query Select Dengan Tuple Sebagai Kondisi di Where Clause

Salam SQL ^_^)!

Kali ini saya mau berbagi pengalaman untuk menggunakan tuple dalam query (kondisi di WHERE clause).

Beberapa minggu yang lalu saya harus melakukan cek data, dimana saya membuat query yang membutuhkan beberapa kombinasi kondisi yang harus dipenuhi. Jika menggunakan operator logical biasa, eg:


WHERE column1=value1 AND column2=value2 AND column3=value3


saya mengalami kesulitan apabila value1..3 tersebut terdiri dari beberapa row yang merupakan hasil subquery dalam clause IN.

Setelah googling ternyata clause WHERE sudah mendukung penggunaan tuple, jadi query yang saya buat menjadi


WHERE (column1, column2, column3)
 IN (SELECT value1, value2, value3 FROM ...)


Wah, saya baru tahu hahaha ^_^)!

Bash | Solusi "Warning: remote port forwarding failed for listen port 9000"

Halo Sobat, mohon maaf saya cukup lama hiatus di blog ini. *sok pakai kata hiatus :P

Langsung saja saya mau share pengalaman melakukan remote debugging PHP melalui ssh tunnel di port 9000 (standar port xdebug, yap saya menggunakan xdebug untuk debugging aplikasi PHP).

Dengan ssh tunnel kita bisa menforward port 9000 dari server yang ada di cloud ke port 9000 di komputer lokal kita, sehingga kita bisa mendebug aplikasi di server melalui IDE/tool debug di komputer lokal. (Saya penyuka PHPStorm, please no IDE war here haha).

Namun karena internet yang saya pakai tidak stabil sehingga seringkali ssh tunnel ini freeze di bash window, sehingga saya harus menutup paksa window tersebut. Akibatnya di sisi server, port forwarding masih aktif, jadi ketika saya melakukan tunneling lagi maka akan muncul warning remote port forwarding failed for listen port 9000.

Solusinya adalah kita harus meng-kill proses port forwarding tsb via ssh ke server dengan menjalankan perintah

  • lsof | grep 9000
    , maka akan muncul list proses, kemudian jalankan
  • kill <pid proses>
    untuk mematikan proses
Setelah selesai maka kita bisa melakukan port forwarding 9000 via ssh tunnel kembali.

referensi: https://gist.github.com/travist/2562314

Sunday, June 26, 2016

Hardware | Banyak Bersyukur dengan SSD

Seperti yang sudah saya sampaikan pada post sebelumnya, kali ini saya mau membahas upgrade laptop saya ke SSD sebagai "main" hard drive.

Saya sudah cukup banyak mendengar mengenai hebatnya kecepatan yang ditawarkan SSD, namun belum mempunyai keinginan untuk upgrade karena ketidaktahuan saya bahwa ada cara untuk memasang SSD ke laptop secara mandiri (*Saya beralih dari PC ke laptop karena adik saya membutuhkan PC saya). Beruntung saya mengikuti feed dari blog Mas Vatih dan menemukan satu artikel menarik mengenai cara memasang SSD di Macbook miliknya.

Berbekal info dari post tersebut dan uang tabungan yang cukup, saya memutuskan untuk mencobanya.
Saya membeli SSD Crucial MX200 250GB dan HDD Caddy SATA 12.7mm dari JakartaNotebook.com *bukan iklan.
Bagi yang belum tahu, HDD Caddy adalah suatu alat yang digunakan untuk memasang hard drive pada slot DVD ROM.
Berikut penampakan HDD Caddy

HDD Caddy 12.7mm *mirip DVD ROM kan ^^


Perlu diketahui juga bahwa HDD Caddy mempunyai 2 ukuran ketebalan yakni 9.5mm dan 12.7mm, yakni sama dengan ketebalan DVD ROM pada laptop. Jadi sebelum membeli, pastikan kita sudah mengetahui ukuran DVD ROM dari laptop kita.

Untuk proses pemasangan cukup mudah, tergantung dari laptop anda, yakni dengan melepas DVD ROM. Saya sudah "tidak membutuhkankan" DVD ROM yang hampir tidak pernah digunakan, jadi apabila sahabat masih membutuhkan DVD ROM, silahkan dipikirkan sebelum memutuskan untuk menggantinya dengan HDD Caddy.
Cara melepas DVD ROM sangat bergantung dari model/merk laptop kita, jadi silahkan googling ya hehe ^^.

Selanjutnya adalah pasang SSD pada HDD Caddy, jangan lupa untuk memasang bautnya dengan benar. Berikutnya adalah kita tinggal memasang HDD Caddy pada slot DVD ROM.
Booting laptop dan voila, seharusnya BIOS sudah bisa mendeteksi SSD yang terpasang.

Note:
Entah kenapa SSD pada HDD Caddy tidak bisa dijadikan sebagai boot hard drive, tapi karena saya menggunakan Ubuntu, saya bisa mensetting agar grub meload OS dari SSD.
Sejauh ini saya puas dengan performa dari SSD baik itu dari sisi booting time maupun compile time ketika coding.

Programmer memang tidak jago dalam benerin komputer, tapi tidak ada salahnya untuk belajar.

Sunday, April 24, 2016

Kotlin | kotlin.String steroid untuk java.lang.String

Sama seperti String di Java, Kotlin String adalah obyek immutable yang berarti sekali diinisialisasi, valuenya tidak akan bisa diubah. Jika dilakukan assignment value baru, yang sebenarnya terjadi adalah JVM akan membuat obyek String baru dengan value yang diassign.

String kode = "Sebenarnya hubungan kita ini apa sih?";
// misalkan object di memory adalah ABC
kode = "Oke, besok aku datang ke Ayah kamu";
// object yang ada di memory saat ini adalah XYZ

Seperti halnya dengan Java, String literal di Kotlin juga dimulai dengan tanda petik ganda (").
Hanya saja class String di Kotlin memeliki beberapa kelebihan dibanding String di Java.
Diantaranya:
  1. Setiap element character dari string bisa diakses dengan array syntax
    eg: kode[index], sedangkan di Java kode.charAt(index)

    Untuk iterasi tiap element

    Java
    for (char c : kode.toCharArray()) {
        System.out.println(c);
    }

    Kotlin
    for (c in kode) {
        println(c)
    }
    
    
  2. String template, yakni dalam string literal bisa disisipkan kode untuk dievaluasi nilainya.
    Di Scala ada fitur yang serupa bernama String interpolation.

    Jika di Java kita biasa menulis seperti ini
    System.out.println(
            String.format("Panjang karakter dari (%s) adalah %d",
                    kode, kode.length()));


    Di Kotlin kita bisa menulis seperti ini
    println("Panjang karakter dari ($kode) adalah ${kode.length}")
    
    
  3. Multiline String literal,
    Bagi kita yang biasa menulis string panjang seperti query mungkin agak kurang nyaman
    dengan tidak adanya fitur multiline string di Java, padahal sudah banyak request masuk untuk menyediakan fitur ini.

    Java
    System.out.println("SELECT '" + kode + "', '" + kode.length() + "'" +
            " FROM tablename" +
            " WHERE blabla");

    Kotlin
    println("""SELECT '$kode', '${kode.length}' 
    FROM tablename 
    WHERE blabla""")

Wednesday, April 20, 2016

I'm not that fanatic anymore ^^!

Haiiii *impersonate cara Takeru Satoh mengucapkan hai (iya dalam bahasa Jepang) di dorama Emperor's Cook :P

Yak, sesuai judul post kali ini, saya sudah tidak sefanatik dulu terhadap bahasa pemrograman yang saya gunakan, yakni Java. Semua berawal ketika saya mengenal JVM language lain (bahasa pemrograman yang berjalan di Java Virtual Machine) seperti :

  1. Groovy yang mengusung Dynamic Typing

    Bagi programmer dynamic type seperti PHP mungkin akan merasa familiar dengan Groovy, karena kita tidak perlu mendeklarasikan tipe data pada variable. Saya sempat jatuh cinta pada bahasa ini, namun saya masih merasakan keamanan "bermain" OOP dengan static type.
  2. Scala dengan konsep Functional OOP (Object Oriented Programming)

    Bahasa ini membuka wawasan saya bahwa diluar pemrograman struktural dan berbasis object (imperative), pernah ada bahasa yang mengusung konsep functional dan belakangan ini mulai muncul lagi ke permukaan dan bahkan banyak menyedot perhatian para developer.
    Functional programming memakai konsep persamaan fungsi dalam matematika x = f(y).
    Jika pada paradigma imperative (OOP) jika menulis bagaimana cara melakukan sesuatu, pada paradigma functional kita menulis apa yang harus dilakukan (deklaratif)

    Sebagai contoh untuk memfilter sebuah arraylist dari Person yang usianya <= 30 tahun

    Imperative

    List<Person> personList = ...
    List<Person> tigaPuluhanPersonList = new ArrayList<>();
    for(Person person : personList){
        if (person.age <= 30) {
            tigaPuluhanPersonList.add(person);   
        }
    }


    Functional

    List<Person> personList = ...
    List<Person> tigaPuluhanPersonList = 
        personList.filter(person -> person.age <= 30);


    Scala menggabungkan kedua konsep ini, yakni OOP dengan static type dan functional sehingga kita bisa memanfaatkan kekuatan OOP dan kemudahan Functional, awesome.
    Hanya saja Scala dibangun oleh kalangan akademisi yakni Martin Odersky dari EFPL Swiss,
    beberapa konsepnya dan syntaxnya agak susah dipahami oleh kalangan non akademisi seperti saya.
    Selain itu, integrasi dengan existing library yang ditulis dengan bahasa Java agak merepotkan.
     
  3. Ceylon yang dibangun oleh Gavin King, sang developer Hibernate ORM yang terkenal itu

    Saya tidak akan membahasnya karena gaung dari bahasa ini tidak seperti Scala maupun 2 bahasa berikut.
  4. Clojure yang membawa Lisp ke ranah JVM

    Yap Clojure adalah bahasa pemrograman yang memakai dialek dari bahasa Lisp.
    Sepengetahuan saya, Clojure cukup populer di kalangan developer yang butuh mengolah data secara significant.
  5. Dan yang paling baru adalah Kotlin yang secara konsep mirip Scala

    Meskipun sama-sama mengusung konsep Functional OOP, Kotlin dirancang dan diclaim oleh Jetbrains (Perusahaan di balik IDE populer Intellij IDEA) sebagai bahasa yang industrial ready (mendukung dengan baik exisisting library yang ditulis dengan bahasa Java).

    I'm fall in love with this language at first code ^ ^)

    Secara syntax masih relatif dekat dengan Java (as programming language), namun jauh mengurangi boilerplate code jika kita menggunakan bahasa Java.

    sebagai contoh adalah type inference (compiler secara otomatis menentukan tipe data dari variable yang dideklarasikan)

    jika kita biasa mendeklarasikan variable dengan cara

    String nama = "Eko Suhariyadi";

    menjadi

    val nama = "Eko Suhariyadi"


Yap, baik pada Groovy, Scala, maupun Kotlin semicolon adalah optional.
No more compile error caused by missing semicolon :P
FYI pada functional programming sangat dianjurkan agar variable di buat immutable
(sekali diinisialiasi tidak bisa diassign dengan value lain), karena lebih aman di sisi concurrency.

Contoh lain adalah lambda expression seperti yang bisa dilakukan dengan Java 8.
Lihat post saya sebelumnya tentang retrolambda.
Saya lebih suka menggunakan Kotlin untuk mendevelop aplikasi berbasis Android.
Tapi tidak menutup kemungkinan saya akan menggunakan Kotlin di aplikasi lain.

Sedangkan bahasa di luar JVM yang saya pakai adalah PHP (yang dulu saya benci) dan Python.
Perkembangan teknologi yang cepat menuntut kita untuk belajar bahasa baru, sesuai dengan kebutuhan "pasar".

Semangat belajar Sob :)

Saturday, April 16, 2016

Java | Retrolambda, Coding dengan Java 8 untuk Java 5, 6, 7

Seperti yang kita ketahui bahwa versi paling akhir untuk saat ini dari Java adalah Java 8.
Pada Java (sebagai bahasa pemrograman) 8 terdapat cukup banyak fitur baru yang memudahkan hidup kita sebagai programmer, terutama untuk mengurangi verbosity/boilerplate dari code yang kita tulis. Fitur-fitur tersebut antara lain adalah lambda expressions, method reference, dan try with resources.

  • Lambda expressions (fitur ini dirilis mulai java 8)

    Sebagai contoh di swing, apabila kita menambahkan actionlistener pada button adalah sebagai berikut

    clickButton.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent event) {
            System.out.println(event);
        }
    });

    terlihat bahwa koding yang kita tulis cukup banyak (verbose), namun dengan lambda expressions kita cukup menuliskan

    clickButton.addActionListener((ActionEvent event) -> {
        System.out.println(event);
    });

    atau bahkan

    clickButton.addActionListener(event -> {
        System.out.println(event);
    });


  • Method reference (fitur ini dirilis mulai java 8)

    Sebenarnya method reference merupakan penyederhaan dari lambda expressions jika anonymous object/method tersebut memanggil method yang sudah ada.

    Dalam contoh kasus clickButton di atas, lambda expressions bisa kita sederhanakan dengan method reference.

    clickButton.addActionListener(System.out::println);

    note: parameter dari method action performed akan dipassing sebagai parameter method
    println
     , ajaib bukan? :)

  • Try with resources (fitur ini dirilis mulai java 7)

    Fitur ini memudahkan kita untuk mengakses resources yang butuh diclose setelah selesai digunakan. eg: read file, data cursor untuk jdbc, etc

    Sebelum Java 7, kita harus menulis koding berikut untuk mengakses file

    String readFirstlineFromFile(String path) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader(path));
    
        try {
            return reader.readLine();
        } finally {
             if (reader != null) reader.close();
        }
    
    }


    Dengan try with resources kita cukup menulis

    String readFirstlineFromFile(String path) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
            return reader.readLine();
        }
    }

Lalu kenapa kita tidak melakukan migrasi agar aplikasi berjalan di JVM 8 saja?
Bisa jadi kita ingin mengadopsi fitur Java 8 tersebut untuk existing app tapi tidak memungkinkan karena sudah dipakai di banyak customer, yang jika dilakukan migrasi membutuhkan ongkos yang besar.

ataupun untuk programmer Android yang ingin mengadopsi fitur Java 8, namun karena Android belum mendukung Java 8 dan kemungkinan akan butuh waktu sebelum Google merilis dukungan Android untuk Java 8.

Dengan retrolambda kebutuhan ini bisa dipenuhi, karena kita bisa koding dengan Java 8 namun hasilnya bisa dieksekusi dengan versi Java (JVM) di bawahnya. Retrolamba akan memodifikasi bytecode hasil kompilasi Java 8 agar bisa dieksekusi di Java 5, 6, 7.

Sebagai informasi tambahan, saat ini retrolambda baru mendukung 3 fitur tersebut di atas.
Belum ada dukungan untuk Stream API dan beberapa fitur Java 8 lainnya.

Cara untuk integrasi ke existing project sangat mudah, karena retrolambda memiliki plugin untuk maven, gradle, maupun kompilasi manual.

May lambda be with you :D

Saturday, March 26, 2016

What i don't like about Mac OS X


Bagi pengguna "fanatik" Mac OSX mungkin judul post kali ini agak mengganggu, tapi ini pengalaman yang saya rasakan sebagai "pengguna baru".

Jadi 2 hari kemarin saya sudah mulai aktif kembali di kantor,
yang mana sebelumnya saya bekerja secara remote dikarenakan alasan kesehatan.
Namun ujian datang ketika saya ingin mulai aktif di kantor.
Pagi hari sebelum berangkat, laptop saya tidak bisa booting, yang ternyata penyebabnya adalah harddisk utama tidak terbaca oleh sistem, alhasil laptop yang sudah menemani saya selama hampir 4 tahun ini harus "dirumah sakitkan".
Saya kontak rekan kantor untuk mengabarkan bahwa saya harus ke service center terlebih dahulu sebelum "ngantor".

Di kantor tidak ada lagi komputer/laptop yang bisa saya gunakan, sehingga saya pun "terpaksa" memakai MacMini second hand yang dimiliki kantor.
Perjuangan dimulai dari sini, karena saya harus mensetup environment yang sama dengan yang saya gunakan di laptop.
Sebagai programmer yang terbiasa bekerja dengan workstation berbasis Ubuntu selama hampir 8 tahun, memang secara UI/UX Mac OS X sangat memukau, namun secara sistem saya sangat menyukai Ubuntu/Debian dengan package managernya.
Di Ubuntu untuk menginstall aplikasi yang saya butuhkan cukup dengan mengetik
apt-get install xxx
(done, aplikasi siap dipakai).
Sedangkan di Mac saya harus mencari installer manual.
Meskipun di Mac ada homebrew/brew untuk menghandle keperluan ini, tetap saja ada kesulitan bagi saya untuk mengatur konfigurasi dari aplikasi, mengecek apakah service sudah jalan atau belum (saya menginstall nginx (dibaca engine X, bukan ngings, hehe) dan php7).
Setelah "rambut saya keriting" dan utak-atik sana sini, duo combi ini masih belum bisa berjalan dengan baik. Padahal di Ubuntu, setelah apt-get install dan beberapa utak-utik, duo combi sudah bisa berjalan dengan baik.

Saya pun memutuskan untuk menggunakan Vagrant saja.
Vagrant adalah sistem yang menggunakan virtual host 
untuk memfasilitasi environtment development. 
Semua kebutuhan development (eg: server, database, etc *kecuali IDE) 
akan diinstall di virtual host ini, dan dihubungkan dengan komputer/laptop host. 
Dengan Vagrant setiap programmer bisa memiliki lingkungan kerja yang sama 
(memiliki spec yang sama dengan komputer production),
jadi tidak ada lagi penyataan, 
"Aplikasi sudah jalan di komputer saya" :D
InsyaAllah saya akan membahas Vagrant di post lain.

Selain packager manager, saya juga tidak menyukai window management dari Mac OSX, khususnya untuk "fullscreen window".
Setidaknya inilah yang saya rasakan sebagai pengguna baru Mac OSX selama 2 hari kemarin.
Bagi pengguna senior Mac OSX, tolong jangan bully saya, saya masih nyubi kakak :D

*Laptop saya sudah selesai diservice selama 2 hari, namun dengan penggantian harddisk baru (bye-bye 4 years of data T_T, mulai dari mp3, mkv, ebook halal dan ebook "haram" *baca: bajakan :D)

*Alhamdulillah saya sudah menyimpan project terbaru saya di harddisk ke-2 di laptop. FYI, saya memodif laptop dengan mengorbankan slot CD/DVD-ROM untuk dipasangi hdd ke-2 dengan menggunakan hdd caddy, yang mungkin akan saya bahas di post lain.

* Tampilan backcover laptop saya, tolong jangan perhatikan stikernya :D


Thursday, March 10, 2016

MySQL | Catatan Pengingat

Saya sangat jarang menggunakan MySQL, karena saya lebih menyukai PostgreSQL untuk development. Saya intensif menggunakan MySQL di semester ke-2, karena ada mata kuliah database (database model design dan querying) yang mana saat itu menggunakan Oracle.
Dikarenakan komputer saya saat itu speknya minim (komputer bekas yang saya beli dari teman kuliah seharga 350ribu rupiah, lengkap), maka saya hanya bisa menginstall MySQL untuk belajar, yang mana saat itu versinya belum mensupport subquery, sehingga saya harus banyak membuat view sebagai alternatif subquery.

Belakangan saya mulai melirik lagi MySQL, namun hanya untuk tujuan belajar.
Berikut catatan atas problem yang saya hadapi, sebagai catatan pengingat jika nanti saya lupa

  • Lupa password user root

    Hari ini saya kelupaan password user root dari MySQL, karena sudah cukup lama tidak tersentuh. Hasil googling mengarahkan saya ke laman ini

    (workstation saya adalah Ubuntu 14.04)
    Langkah pertama adalah stop mysql service

    sudo service mysql stop

    Berikutnya adalah start service mysql dengan opsi --skip-grant-tables
    yang berguna untuk mendisable authentikasi untuk mengakses mysql prompt.
    Di PostgreSQL ini sama dengan mengeset authentikasi user postgres menjadi trust.
    Saya mencoba mengedit script di /etc/init.d/mysql, namun ketika start, opsi tersebut tidak berjalan, sehingga saya harus menstart mysql server dengan command

    sudo mysqld_safe --skip-grant-tables

    selanjutnya ketika bisa langsung masuk ke mysql prompt dengan mengetik mysql
    mysql

    setelah masuk di mysql prompt jalankan perintah berikut

    mysql> FLUSH PRIVILEGES;

    #untuk mysql versi 5.7.6 keatas, ketik perintah berikut untuk mengganti password user root
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password_baru';

    #sedangkan untuk mysql versi 5.7.5 kebawah, ketik perintah berikut
    mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('password_baru');


    Setelahnya tutup proses mysqld_safe --skip-grant-tables dan restart mysql secara normal

    sudo service mysql start

    maka kita bisa login kembali ke mysql prompt sebagai user root dengan password baru
  • Menjalankan file sql di dalam mysql prompt

    Jika di PostgreSQL kita bisa menjalankan file sql dalam psql prompt dengan mengetik

    \i path_to_file.sql


    Dan untuk di MySQL kita harus mengetik

    \. path_to_file.sql


    Berbeda dengan psql prompt yang mempunyai autocomplete path dengan menekan tab,
    di mysql prompt kita harus mengetik manual lokasi file sql, jika posisi directory saat kita mengakses mysql prompt berbeda dengan lokasi file.

*The end

Saturday, June 21, 2014

Raspberry Pi | Problem Monitor Out of Range 60Hz

Halo apa kabar sahabat sekalian? Semoga sahabat semua senantiasa dalam limpahan kebaikan dari Allah SWT, aamiin.

Sudah lama saya tidak posting di blog ini, hehehe maklum orang sok sibuk :D.

Kali ini saya ingin berbagi mengenai Raspberry Pi, lebih tepatnya saya menggunakan varian Banana Pi. Karena ada tugas kantor, saya harus mencoba komputer mungil ini di rumah (sekalian ngoprek).
Berbekal konverter HDMI to VGA saya mencoba menghubungkan Banana Pi ke LCD monitor 19", namun ternyata ada masalah, yakni muncul informasi "Out of Range bla bla".

Setelah googling sebentar saya menemukan link berikut, dan saya mendapatkan pencerahan bahwa untuk mengatasi hal ini kita bisa mengedit file config.txt.

Jadi berikut hal-hal yg saya lakukan:

  1. Mencabut sdcard dari banana pi dan memasangnya ke laptop
  2. Saya edit file config.txt yg ada di folder BOOT
    • uncomment 2 baris berikut, jika belum ada mungkin sahabat bisa menambahkannya sendiri
      • hdmi_group=1 
      • hdmi_mode=1
  3. Setelah editing selesai jangan lupa simpan file, dan cabut sdcard dari laptop (jangan lupa dieject dulu loh ya :P)
  4. Pasang kembali sdcard pada banana pi, dan lakukan booting kembali
  5. Maka hasilnya.... voila
Raspberry Pi | Banana Pi
Banana Pi on Action