Skip to content

Instantly share code, notes, and snippets.

View olivergeorge's full-sized avatar

Oliver George olivergeorge

  • Tasmania, Australia
View GitHub Profile
@olivergeorge
olivergeorge / analyse_code.clj
Last active April 14, 2022 00:13
most used keywords in codebase
(ns cnd.analyse-code
"Use rewrite-clj zipper to walk code.
Niggles
* Doesn't use the (ns...) aliases to resolve aliases to full paths.
"
(:require [clojure.java.io :as io]
[clojure.zip :as zip]

This is a bit of a thought exercise. I doubt it’s perfect and I’m hoping for opinions and corrections with the goal of a well reasoned practical approach.

Motivation...

One way to look at type declarations in a static language is as a test which picks up potential incompatible code paths. E.g. data passed is incompatible with code.

In static languages the effort to write the test is reduced by virtue of being declared inline with the code and inference allows a few annotations to permeate - having said that we can achieve a similar results in Clojure.

Quick scan of tools at hand...

I was struggling to compose datomic queries neatly. In the end I googled and found a blogpost which proposed a sane solution.

My motivation was an API endpoint with optional filters. I'd like my query include additional filters based on the args present.

Anyway, here's how my code ended up looking...

And the article: http://grishaev.me/en/datomic-query

Fix is to link openssl@1.1 as openssl

1069  cd /opt/homebrew/opt                 # OR WHEREVER?
1070  rm openssl
1071  ln -s openssl@1.1 openssl
@olivergeorge
olivergeorge / db-spec.clj
Last active September 24, 2021 12:55
Simple script to generate clojure.spec info for a database.
(ns db-spec.core
(:require [clojure.java.jdbc :as j]
[clojure.spec :as s])
(:import (java.sql Types)))
(defn db-tables-raw
[db-spec {:keys [catalog schemaPattern tableNamePattern]}]
(j/with-db-metadata [meta db-spec]
(j/metadata-result
(.getTables meta catalog schemaPattern tableNamePattern (into-array String ["TABLE"])))))

Looking at some old code there were a couple of undesirable features. One particular code smell is a good motiviating example: handlers calling other handlers.

It encourages the developer to "register handlers as reusable components" but that's a pretty clumsy way to write utilties. Over time those util handlers were collecting barnicles and were becoming very hard to reason about or refactor.

Handlers, actions and utils

With the advent of :fx we have a clean composable alternative with some desirables traits.

My app has three namespaces (app.handlers, app.actions and app.utils)

@olivergeorge
olivergeorge / deps.edn
Created August 22, 2021 23:36
Create calendars from your git commits. Produces a CSV which Google Calendar can import.
{:deps {clj-jgit/clj-jgit {:mvn/version "1.0.1"}
org.clojure/data.csv {:mvn/version "1.0.0"}}}
@olivergeorge
olivergeorge / Makefile
Last active August 13, 2021 02:06
Devops tools for simple Datomic Ions app
provision:
clojure -A:dev -m devops provision
teardown:
clojure -A:dev -m devops teardown
cloud-on:
clojure -A:dev -m devops cloud-on
from django.core.exceptions import ValidationError
from django.db.models import Field, CharField
__all__ = ['MultiColumnField']
try:
from hashlib import md5
except ImportError:
from md5 import new as md5

Some code to generate an SQLite dump from a database via a JDBC connection.

First we need a deps.edn file

{:deps {org.clojure/java.jdbc {:mvn/version "0.7.12"}
        org.xerial/sqlite-jdbc {:mvn/version "3.34.0"}
        com.oracle.database.jdbc/ojdbc8 {:mvn/version "21.1.0.0"}}}