lca 0.2.8 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a16c5260b03c32b7338e2afc954b3b7e81cdac0d70281b381572cef31c4e2100
4
- data.tar.gz: fb743e4d069c4768b3cb75fd8bd38774a5600148078e1d84bd7dc26e6686c351
3
+ metadata.gz: 4241582f64a255663e4373e4ee06379ae8edf402fa4734c277c5ad35ed14b89b
4
+ data.tar.gz: 2527b01719ade3f96e32a56db8b41fceb4b0fe53eb3842952d0f5ab557f8c1b5
5
5
  SHA512:
6
- metadata.gz: d0cb142ada744da2836415053fd8e5aa246463d2921dea9ad3b0f92aa1a6c88fe5e50fefdae34189ca6cee87a0bd664fdad47447737d364b1f39018518c3c517
7
- data.tar.gz: 28bfb9f87f16d36ed059db06a4aa91de7d8b3390b2f49c3f69e74519958d093b64fbdfebb753e26fead95f8fe49aec7352742545f17559bed53e652ffe311316
6
+ metadata.gz: f84aecada0b22ea9d6970cba1f566c83f327b6ea0b3c02c0e4dfaf897dda339e541abe1fa11f42313bc34f4e361949569d8693aab641e320ed5d79d5512471da
7
+ data.tar.gz: d2baddc6bc49012c379e97e03f65f4159fa26bc9fbc96dee744db3222b7a97626323ae73e88a1064e8268e72c174eac835a5c05d76d592d09f27f6118c44d6c4
data/Gemfile CHANGED
@@ -8,8 +8,6 @@ gem "rake", "~> 13.0"
8
8
  gem "rspec", "~> 3.0"
9
9
 
10
10
  gem "activerecord", "~> 6.0"
11
- gem "activestorage", "~> 6.0"
12
- gem "actiontext", "~> 6.0"
13
-
11
+ gem "active_tree", "~> 0.3.2"
14
12
  gem "jwt"
15
13
  gem "pg_ltree"
data/Gemfile.lock CHANGED
@@ -1,87 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lca (0.1.18)
5
- actiontext (~> 6.0)
4
+ lca (0.3)
5
+ active_tree (~> 0.3)
6
6
  activerecord (~> 6.0)
7
- activestorage (~> 6.0)
8
7
  jwt (~> 2.2.3)
9
8
  pg_ltree (~> 1.1.8)
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
13
12
  specs:
14
- actionpack (6.1.4.1)
15
- actionview (= 6.1.4.1)
16
- activesupport (= 6.1.4.1)
17
- rack (~> 2.0, >= 2.0.9)
18
- rack-test (>= 0.6.3)
19
- rails-dom-testing (~> 2.0)
20
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
21
- actiontext (6.1.4.1)
22
- actionpack (= 6.1.4.1)
23
- activerecord (= 6.1.4.1)
24
- activestorage (= 6.1.4.1)
25
- activesupport (= 6.1.4.1)
26
- nokogiri (>= 1.8.5)
27
- actionview (6.1.4.1)
28
- activesupport (= 6.1.4.1)
29
- builder (~> 3.1)
30
- erubi (~> 1.4)
31
- rails-dom-testing (~> 2.0)
32
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
33
- activejob (6.1.4.1)
34
- activesupport (= 6.1.4.1)
35
- globalid (>= 0.3.6)
13
+ active_tree (0.3.1)
14
+ activerecord (~> 6.0)
15
+ jwt (~> 2.2.3)
16
+ pg_ltree (~> 1.1.8)
36
17
  activemodel (6.1.4.1)
37
18
  activesupport (= 6.1.4.1)
38
19
  activerecord (6.1.4.1)
39
20
  activemodel (= 6.1.4.1)
40
21
  activesupport (= 6.1.4.1)
41
- activestorage (6.1.4.1)
42
- actionpack (= 6.1.4.1)
43
- activejob (= 6.1.4.1)
44
- activerecord (= 6.1.4.1)
45
- activesupport (= 6.1.4.1)
46
- marcel (~> 1.0.0)
47
- mini_mime (>= 1.1.0)
48
22
  activesupport (6.1.4.1)
49
23
  concurrent-ruby (~> 1.0, >= 1.0.2)
50
24
  i18n (>= 1.6, < 2)
51
25
  minitest (>= 5.1)
52
26
  tzinfo (~> 2.0)
53
27
  zeitwerk (~> 2.3)
54
- builder (3.2.4)
55
28
  concurrent-ruby (1.1.9)
56
- crass (1.0.6)
57
29
  diff-lcs (1.4.4)
58
- erubi (1.10.0)
59
- globalid (0.5.2)
60
- activesupport (>= 5.0)
61
30
  i18n (1.8.10)
62
31
  concurrent-ruby (~> 1.0)
63
32
  jwt (2.2.3)
64
- loofah (2.12.0)
65
- crass (~> 1.0.2)
66
- nokogiri (>= 1.5.9)
67
- marcel (1.0.1)
68
- mini_mime (1.1.1)
69
33
  minitest (5.14.4)
70
- nokogiri (1.12.4-x86_64-linux)
71
- racc (~> 1.4)
72
34
  pg (1.2.3)
73
35
  pg_ltree (1.1.8)
74
36
  activerecord (>= 4.0.0, <= 7.0.0.rc1)
75
37
  pg (>= 0.17.0, < 2)
76
- racc (1.5.2)
77
- rack (2.2.3)
78
- rack-test (1.1.0)
79
- rack (>= 1.0, < 3)
80
- rails-dom-testing (2.0.3)
81
- activesupport (>= 4.2.0)
82
- nokogiri (>= 1.6)
83
- rails-html-sanitizer (1.4.2)
84
- loofah (~> 2.3)
85
38
  rake (13.0.6)
86
39
  rspec (3.10.0)
87
40
  rspec-core (~> 3.10.0)
@@ -104,12 +57,13 @@ PLATFORMS
104
57
  x86_64-linux
105
58
 
106
59
  DEPENDENCIES
107
- actiontext (~> 6.0)
60
+ active_tree (~> 0.3.1)
108
61
  activerecord (~> 6.0)
109
- activestorage (~> 6.0)
62
+ jwt
110
63
  lca!
64
+ pg_ltree
111
65
  rake (~> 13.0)
112
66
  rspec (~> 3.0)
113
67
 
114
68
  BUNDLED WITH
115
- 2.2.27
69
+ 2.2.29
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Gem Version](https://badge.fury.io/rb/lca.svg)](https://badge.fury.io/rb/lca)
1
+ [![Tests](https://github.com/nicksterious/lca/actions/workflows/ci.yml/badge.svg)](https://github.com/nicksterious/lca/actions/workflows/ci.yml) [![Ruby Gem](https://github.com/nicksterious/lca/actions/workflows/rubygems.yml/badge.svg)](https://github.com/nicksterious/lca/actions/workflows/rubygems.yml) [![Gem Version](https://badge.fury.io/rb/lca.svg)](https://badge.fury.io/rb/lca)
2
2
 
3
3
  # LCA
4
4
 
@@ -24,15 +24,24 @@ Or install it yourself as:
24
24
 
25
25
  $ gem install lca
26
26
 
27
- Upon installing the gem you must run the install process in your Rails application's root:
27
+ Upon installing the gem you must run the ActiveTree install process in your Rails application's root:
28
+
29
+ $ rails g active_tree:install
30
+
31
+
32
+ This will generate a `config/active_tree.yml` which you may customize to your needs, an initializer and a migration file which you can also customize to add any database columns your models will require.
33
+
34
+ You must also run the LCA gem install generator:
28
35
 
29
36
  $ rails g lca:install
30
37
 
31
- This will generate a `config/lca.yml` which you may customize to your needs, an initializer and a migration file which you can also customize to add any database columns your models will require.
38
+
39
+ This will create a migration file which you can edit to add your models' specific attributes.
40
+
32
41
 
33
42
  ## Usage
34
43
 
35
- Include the LCA concern into one of your models which will own lifecycle trees (owner model):
44
+ Include the ActiveTree concern into one of your models which will own lifecycle trees (owner model):
36
45
 
37
46
  ```ruby
38
47
  class User < ApplicationRecord
@@ -45,16 +54,16 @@ This will extend your model and enable the following functionality:
45
54
 
46
55
  ```ruby
47
56
  # query with ActiveRecord syntax
48
- User.last.lca_cycles
49
- User.find_by(name: "Acme").lca_cycles.impacts.select("impact_unit, sum(impact_amount) as total_impact").group(:impact_unit)
50
- User.last.lca_cycles.where(...)
51
- User.last.lca_cycles.where(...).group(...)
52
- User.last.lca_cycles.where(...).limit(...).offset(...)
57
+ User.last.active_trees
58
+ User.find_by(name: "Acme").active_trees.impacts.select("impact_unit, sum(impact_amount) as total_impact").group(:impact_unit)
59
+ User.last.active_trees.where(...)
60
+ User.last.active_trees.where(...).group(...)
61
+ User.last.active_trees.where(...).limit(...).offset(...)
53
62
 
54
63
  # AR query with ltree syntax
55
- User.last.lca_cycles.disabled.match_path("*.CustomProcess.*")
56
- User.last.lca_cycles.match_path("*{5,10}.CustomProcess.*.Ecosphere.*")
57
- User.last.lca_cycles.active.match_path("*.WhateverProcess.*.Ecosphere.*.CO2Emission.*").where( impact_amount: [100..150]).sum(:impact_amount)
64
+ User.last.active_trees.disabled.match_path("*.CustomProcess.*")
65
+ User.last.active_trees.match_path("*{5,10}.CustomProcess.*.Ecosphere.*")
66
+ User.last.active_trees.active.match_path("*.WhateverProcess.*.Ecosphere.*.CO2Emission.*").where( impact_amount: [100..150]).sum(:impact_amount)
58
67
 
59
68
  Lca::Cycle.match_path("Top.Electric Vehicle.*").impacts.match_path("*.CO2*").where( impact_amount: [ 1000..10000 ]).average(:impact_amount)
60
69
  Lca::Cycle::Product.where(name: "Electric Vehicle Battery").impacts.match_path("*.Cobalt.*").sum(:impact_amount)
@@ -64,11 +73,11 @@ Lca::Exchange.match_path("*.Oil.*.Ecosphere.*").impacts.sum(:impact_amount)
64
73
  Lca::Product.match_path("*.ElectricVehicle.*").processes.match_path("*.Processing.*").where(location: "EU").impacts.match_path("*.Lithium.*").where(location: ["CN", "Africa"]).sum(:impact_amount)
65
74
 
66
75
  # pg_ltree queries
67
- User.last.lca_cycles.last.parent
76
+ User.last.active_trees.last.parent
68
77
  Lca::Process.match_path("*.Manual assembly.*").children
69
78
 
70
79
  # pg_ltree combined with AR syntax
71
- User.last.lca_cycles(type: "Lca::Product").children.match_path("*.Retail").children.exchanges
80
+ User.last.active_trees(type: "Lca::Product").children.match_path("*.Retail").children.exchanges
72
81
 
73
82
  # all queries can be directed to a specific partition:
74
83
  Lca::Process.owned_by( owner_id ).match_path("*.Recycling.*").where(impact_unit: "tons CO2/year").impacts.sum(:impact_amount)
@@ -83,12 +92,13 @@ Lca::Impact::Ecosphere::Fauna.match_path("*.ResourceExtraction.*").where(impact_
83
92
  ```
84
93
 
85
94
  To see what syntax to use for path traversal please check out the following resources:
95
+ * active_tree gem https://github.com/nicksterious/active_tree
86
96
  * pg_ltree gem https://github.com/sjke/pg_ltree
87
97
  * Postgres ltree extension documentation https://www.postgresql.org/docs/9.1/ltree.html
88
98
 
89
- The LCA gem is designed to be compatible with PostgREST. PostgREST is an amazing tool that generates a CRUD REST API for your Postgres database, read more about it here: https://postgrest.org
99
+ ## Scalability
90
100
 
91
- If the `create_postgrest_roles` setting is on each new owner will be assigned a Postgres role allowing them to access data within their partition using PostgREST. Your owner model will be extended with a `.generate_jwt` method you can use to generate the PostgREST authentication token.
101
+ All LCA data can be stored into separate partitions using the ActiveTree partitioning feature. See `config/active_tree.yml` for table and partitioning naming and options.
92
102
 
93
103
  ## Caveats
94
104
 
@@ -110,7 +120,6 @@ Lca::Process.last.children.unscope(where: :type).impacts.where(impact_amount: 50
110
120
  * .child / .parent query support across models unrelated through inheritance
111
121
  * more model templates for various LCA cycles, processes and impacts
112
122
  * model validations
113
- * query objects
114
123
  * postgres RECURSIVE queries
115
124
  * builders
116
125
  * seeds/fixtures
@@ -120,10 +129,6 @@ Lca::Process.last.children.unscope(where: :type).impacts.where(impact_amount: 50
120
129
 
121
130
  Bug reports, pull requests and feature suggestions are welcome on GitHub at https://github.com/nicksterious/lca
122
131
 
123
- ## Sponsors
124
-
125
- We welcome any sponsorship through Github Sponsors. All corporate sponsors' logo and URL of choice shall show up within this section.
126
-
127
132
  ## License
128
133
 
129
134
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -10,17 +10,6 @@ module Lca
10
10
  migration_template "migration.rb.tt", "db/migrate/install_lca.rb", migration_version: migration_version
11
11
  end
12
12
 
13
- def copy_initializer
14
- copy_file 'initializer.rb.tt', 'config/initializers/lca.rb'
15
- end
16
-
17
- def copy_config
18
- conf_file = "config/lca.yml"
19
- copy_file "config.yml.tt", conf_file
20
- contents = File.read( conf_file ).gsub("changeme", ('a'..'z').to_a.shuffle.first(4).join )
21
- File.open(conf_file, 'wb') { |file| file.write(contents) }
22
- end
23
-
24
13
  def migration_version
25
14
  "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
26
15
  end
@@ -1,81 +1,18 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
 
4
- # enable ltree extension
5
- begin
6
- execute "create extension ltree"
7
- rescue
8
- p "LTREE was already enabled"
9
- end
10
-
11
-
12
- # create the main table as set up within LCA_OPTIONS[:table_name]
13
- execute <<-SQL
14
- create table #{ LCA_OPTIONS[:table_name] } (
15
- id serial,
16
-
17
- owner_id integer,
18
- owner_type character varying,
19
-
20
- status integer,
21
-
22
- data_external_id character varying,
23
- data_provider character varying,
24
-
25
- type character varying,
26
- name text,
27
-
28
- parent_entity_id integer,
29
- parent_entity_type character varying,
30
-
31
- path ltree,
32
- path_slug text,
33
-
34
- metadata_inline jsonb,
35
-
36
- impact_amount decimal,
37
- impact_amount_previous decimal,
38
- impact_amount_unit text,
39
- impact_factor decimal,
40
- impact_precision decimal,
41
-
42
- created_at timestamp(6) without time zone not null,
43
- updated_at timestamp(6) without time zone not null,
44
-
45
-
46
- primary key (id, owner_id)
47
- ) partition by list(owner_id)
48
- SQL
49
-
50
- # create an "others" partition for when the owner is undefined/unknown? just in case / may help in some edge cases
51
- execute "CREATE TABLE #{LCA_OPTIONS[:table_name]}_others PARTITION OF #{LCA_OPTIONS[:table_name]} DEFAULT"
52
-
53
-
54
- # add indexes
55
- add_index LCA_OPTIONS[:table_name], :id
56
- add_index LCA_OPTIONS[:table_name], :owner_id
57
- add_index LCA_OPTIONS[:table_name], :type
58
- add_index LCA_OPTIONS[:table_name], :parent_entity_id
59
-
60
- # next two indexes unfortunately can't be unique since a cycle can appear several times under an owner
61
- add_index LCA_OPTIONS[:table_name], :path, using: :gist
62
- add_index LCA_OPTIONS[:table_name], [:data_provider, :data_external_id]
63
-
64
-
65
- # when postgrest is enabled...
66
- if LCA_OPTIONS[:create_postgrest_roles]
67
- # create postgrest anon user with no privs
68
- # postgrest may pass an user's role using JWT
69
- execute "drop role if exists postgrest_anon"
70
- execute "create role postgrest_anon nologin"
71
- execute "grant postgrest_anon to #{ LCA_OPTIONS[:database_user] }"
72
- end
4
+ # add any columns required by your business model
5
+ add_column ACTIVE_TREE_OPTIONS[:table_name], :impact_amount, :decimal
6
+ add_column ACTIVE_TREE_OPTIONS[:table_name], :impact_amount_previous, :decimal
7
+ add_column ACTIVE_TREE_OPTIONS[:table_name], :impact_amount_unit, :text
8
+ add_column ACTIVE_TREE_OPTIONS[:table_name], :impact_factor, :decimal
9
+ add_column ACTIVE_TREE_OPTIONS[:table_name], :impact_precision, :decimal
73
10
 
74
11
 
75
12
  # snapshots table
76
13
  # maybe this should only store the impacts?
77
14
  execute <<-SQL
78
- create table #{ LCA_OPTIONS[:table_name] }_snapshots (
15
+ create table #{ ACTIVE_TREE_OPTIONS[:table_name] }_snapshots (
79
16
  id serial,
80
17
 
81
18
  impact_id integer,
@@ -97,22 +34,10 @@ SQL
97
34
  SQL
98
35
 
99
36
  # index the snapshots table
100
- add_index "#{LCA_OPTIONS[:table_name]}_snapshots", :id
101
- add_index "#{LCA_OPTIONS[:table_name]}_snapshots", :owner_id
102
- add_index "#{LCA_OPTIONS[:table_name]}_snapshots", :impact_id
103
- add_index "#{LCA_OPTIONS[:table_name]}_snapshots", :created_at
37
+ add_index "#{ACTIVE_TREE_OPTIONS[:table_name]}_snapshots", :id
38
+ add_index "#{ACTIVE_TREE_OPTIONS[:table_name]}_snapshots", :owner_id
39
+ add_index "#{ACTIVE_TREE_OPTIONS[:table_name]}_snapshots", :impact_id
40
+ add_index "#{ACTIVE_TREE_OPTIONS[:table_name]}_snapshots", :created_at
104
41
 
105
-
106
- # metadata table
107
- create_table "#{ LCA_OPTIONS[:table_name] }_metadata" do |t|
108
- t.string :model_type
109
- t.integer :model_id
110
- t.string :key
111
- t.text :value
112
-
113
- t.timestamps
114
- end
115
- add_index "#{ LCA_OPTIONS[:table_name] }_metadata", [ :model_type, :model_id ]
116
- add_index "#{ LCA_OPTIONS[:table_name] }_metadata", [ :key ]
117
42
  end
118
43
  end
@@ -7,82 +7,50 @@ module Lca
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
+ before_destroy :lca_delete_storage
10
11
 
11
- has_many :lca_cycles, class_name: "::Lca::Model", foreign_key: :owner_id, as: :owner
12
- after_create :lca_create_storage
13
- before_destroy :lca_delete_storage
12
+ include ActiveTree::ActiveTreeAble
13
+ after_create :lca_create_storage
14
14
 
15
- # instance methods
16
- def lca_role
17
- "lca_owner_#{id}_#{ LCA_OPTIONS[:owner_role_suffix] }"
18
- end # role
15
+ has_many :lca_cycles, class_name: "::Lca::Model", foreign_key: :owner_id, as: :owner
19
16
 
20
- # Generates a JWT token the client (SPA) can pass to PostgREST for privilege escalation
21
- def generate_jwt
22
- payload = { role: self.lca_role }
23
- ::JWT.encode payload, LCA_OPTIONS[:jwt_secret], LCA_OPTIONS[:jwt_encryption]
24
- end # .generate_jwt
17
+ alias_method :lca_role, :active_tree_role
18
+ alias_method :jwt_token, :generate_jwt
19
+ alias_method :lca_store, :store
25
20
 
21
+ def lca_table_name
22
+ store.options[:table_name]
23
+ end # lca_table_name
26
24
 
27
- # Returns the LCA table name as configured within config/lca.yml
28
- def lca_table_name
29
- LCA_OPTIONS[:table_name]
30
- end # .lca_table_name
31
25
 
26
+ def lca_create_storage
27
+ # create snapshots partition
28
+ lca_sql "create table if not exists #{lca_table_name}_snapshots_#{id} partition of #{lca_table_name}_snapshots for values in (#{id})"
29
+
30
+ # if roles are enabled, grant privileges
31
+ if ACTIVE_TREE_OPTIONS[:create_postgrest_roles]
32
+ lca_sql "grant all privileges on #{lca_table_name}_snapshots_#{id} to #{ lca_role }"
33
+ end
34
+ end # lca_create_storage
32
35
 
33
- # Creates LCA table partition and role for owner
34
- def lca_create_storage
35
36
 
36
- # create data partition
37
- lca_sql "create table if not exists #{lca_table_name}_#{id} partition of #{lca_table_name} for values in (#{id})"
38
- # TODO create partition indexes
37
+ def lca_delete_storage
38
+ # remove privs
39
+ if store.options[:create_postgrest_roles]
40
+ lca_sql "REVOKE ALL PRIVILEGES ON #{lca_table_name}_snapshots_#{id} FROM #{ lca_role }"
41
+ end
39
42
 
40
- # create snapshots partition
41
- lca_sql "create table if not exists #{lca_table_name}_snapshots_#{id} partition of #{lca_table_name}_snapshots for values in (#{id})"
42
- # TODO create partition indexes
43
+ if store.options[:destroy_partition_on_owner_destroy]
44
+ lca_sql "drop table if exists #{lca_table_name}_snapshots_#{id}"
45
+ else
46
+ lca_sql "alter table #{lca_table_name}_snapshots detach partition #{ lca_role }"
47
+ end
48
+ end # lca_delete_storage
43
49
 
44
- if LCA_OPTIONS[:create_postgrest_roles]
45
- # drop role if it exists
46
- lca_sql "drop role if exists #{ lca_role }"
47
-
48
- # create role
49
- lca_sql "create role #{ lca_role }"
50
-
51
- # grant privs
52
- lca_sql "grant all privileges on #{lca_table_name}_#{id} to #{ lca_role }"
53
- lca_sql "grant all privileges on #{lca_table_name}_snapshots_#{id} to #{ lca_role }"
54
- end
55
-
56
- end # create_storage
57
-
58
-
59
- # Deletes or detaches the partition and removes the role for this owner
60
- def lca_delete_storage
61
-
62
- if LCA_OPTIONS[:create_postgrest_roles]
63
- # revoke privs
64
- lca_sql "REVOKE ALL PRIVILEGES ON #{lca_table_name}_#{id} FROM #{ lca_role }"
65
- lca_sql "REVOKE ALL PRIVILEGES ON #{lca_table_name}_snapshots_#{id} FROM #{ lca_role }"
66
-
67
- # delete role
68
- lca_sql "drop role #{ lca_role }"
69
- end
70
-
71
- if LCA_OPTIONS[:destroy_partition_on_owner_destroy]
72
- # delete partition
73
- lca_sql "drop table if exists #{lca_table_name}_#{id}"
74
- lca_sql "drop table if exists #{lca_table_name}_snapshots_#{id}"
75
- else
76
- # detach and forget about it
77
- lca_sql "alter table #{lca_table_name} detach partition #{ lca_role }"
78
- lca_sql "alter table #{lca_table_name}_snapshots detach partition #{ lca_role }"
79
- end
80
- end # delete_storage
81
-
82
- def lca_sql sql
83
- ActiveRecord::Base.connection.execute sql
84
- end # lca_sql
85
50
 
51
+ def lca_sql sql
52
+ ActiveRecord::Base.connection.execute sql
53
+ end # lca_sql
86
54
  end # ClassMethods
87
55
  end
88
56
  end
@@ -1,6 +1,7 @@
1
1
  class Lca::Cycle::Product < Lca::Cycle
2
2
  # price?
3
3
  # quantity?
4
+ # quantity unit?
4
5
  # life time?
5
6
  # life time unit?
6
7
  end
@@ -1,4 +1,5 @@
1
1
  class Lca::Cycle::Service < Lca::Cycle
2
2
  # duration?
3
+ # duration unit?
3
4
  # price?
4
5
  end
@@ -3,8 +3,8 @@ class Lca::ImpactSnapshot < ActiveRecord::Base
3
3
  self.primary_key = :id
4
4
 
5
5
  def self.table_name
6
- return "#{::LCA_OPTIONS[:table_name]}_snapshots" if defined? ::LCA_OPTIONS
7
- return "lca_models_snapshots"
6
+ return "#{::ACTIVE_TREE_OPTIONS[:table_name]}_snapshots" if defined? ::ACTIVE_TREE_OPTIONS
7
+ return "active_tree_snapshots"
8
8
  end
9
9
 
10
10
 
@@ -1,78 +1,5 @@
1
- class Lca::Model < ActiveRecord::Base
1
+ class Lca::Model < ActiveTree::Model
2
2
 
3
- include Lca::Statusable
4
3
 
5
- self.primary_key = :id
6
-
7
- ltree :path
8
-
9
- def self.table_name
10
- return ::LCA_OPTIONS[:table_name] if defined? ::LCA_OPTIONS
11
- return "lca_models"
12
- end
13
-
14
- belongs_to :owner, polymorphic: :true, required: true
15
-
16
- scope :match_path, -> (some_path) { where("path ~ ?", "#{some_path}") }
17
-
18
- #has_one_attached :picture
19
- #has_rich_text :description
20
-
21
- validates_presence_of :name, allow_blank: false
22
- validates_presence_of :path, allow_blank: false
23
-
24
- has_many :metadata, class_name: "::Lca::Metadata", dependent: :destroy, as: :model
25
-
26
- before_validation :set_defaults
27
- def set_defaults
28
- self.path ||= name.delete(" ").gsub(/[^0-9a-z ]/i, '') if name
29
- self.path_slug = path.parameterize if path
30
- self.metadata_inline ||= {}
31
- end
32
-
33
-
34
- # Scoping by owner in order to select the partition
35
- #
36
- # @param owner_id [Integer] the partition owner
37
- def self.owned_by(owner_id)
38
- # if we're looking for anything else but an integer, revert to the base class
39
- return self if !owner_id.is_a? Integer
40
-
41
- partition_suffix = "_#{owner_id}"
42
-
43
- table = "#{ self.table_name }#{ partition_suffix }"
44
-
45
- ApplicationRecord.connection.schema_cache.clear!
46
- return self if !ApplicationRecord.connection.schema_cache.data_source_exists? table
47
-
48
- # duplicate the class
49
- model_class = Class.new self
50
- original_class_name = self.name
51
-
52
- # ...for this owner
53
- class_name = "#{name}#{partition_suffix}"
54
-
55
- # specify the table
56
- model_class.define_singleton_method(:table_name) do
57
- table
58
- end
59
-
60
- # specify the name
61
- model_class.define_singleton_method(:name) do
62
- class_name
63
- end
64
-
65
- model_class.define_singleton_method(:sti_name) do
66
- original_class_name
67
- end
68
-
69
- # override the STI name lmfao
70
- model_class.define_singleton_method(:find_sti_class) do |p|
71
- original_class_name.constantize
72
- end
73
-
74
- # proceed
75
- model_class
76
- end # .owned_by
77
4
 
78
5
  end
@@ -1,2 +1,6 @@
1
1
  class Lca::Process::Transport < Lca::Process
2
- end
2
+ # distance?
3
+ # distance unit?
4
+ # duration?
5
+ # duration unit?
6
+ end
@@ -3,4 +3,9 @@ class Lca::Stage < Lca::Model
3
3
  belongs_to :cycle, class_name: "::Lca::Cycle", foreign_key: :parent_entity_id, required: true
4
4
  has_many :processes, class_name: "::Lca::Process", foreign_key: :parent_entity_id
5
5
 
6
+ # duration?
7
+ # duration unit?
8
+
9
+ # quantity?
10
+ # quantity unit?
6
11
  end
@@ -1,8 +1,3 @@
1
- class Lca::Queries::Query
2
-
3
- def valid_input?(v)
4
- return false if [ [], "", "0", 0, nil, [""], [0], ["0"], [nil], "all" ].include?(v)
5
- return true
6
- end
1
+ class Lca::Queries::Query < ActiveTree::Query
7
2
 
8
3
  end
data/lib/lca/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lca
4
- VERSION = "0.2.8"
4
+ VERSION = "0.3.2"
5
5
  end
data/lib/lca.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
- require "active_support/all"
3
2
 
3
+ require "active_support/all"
4
4
  require "active_record"
5
-
6
5
  require "pg_ltree"
6
+ require "active_tree"
7
7
 
8
8
  require_relative "lca/version"
9
9
 
10
- require_relative "lca/models/concerns/statusable"
11
- require_relative "lca/models/metadata"
10
+ require_relative "lca/models/concerns/lcable"
12
11
  require_relative "lca/models/model"
13
12
  require_relative "lca/models/cycle"
14
13
  require_relative "lca/models/stage"
@@ -39,39 +38,12 @@ require_relative "lca/models/impact/ecosphere/flora"
39
38
  require_relative "lca/models/impact/human_health/cancer"
40
39
  require_relative "lca/models/impact/technosphere/resource_availability"
41
40
 
42
- require_relative "lca/models/concerns/lcable"
43
41
  require_relative "lca/active_record"
44
42
 
45
- # TODO add query objects and builders
46
- #require "lca/queries/"
47
- #require "lca/builders/"
48
43
 
49
44
  module Lca
50
45
  class Error < StandardError; end
51
46
 
52
- # Your code goes here...
53
-
54
- class << self
55
- attr_accessor :lca_models
56
- attr_accessor :options
57
- end
58
-
59
- self.lca_models = []
60
-
61
- def self.lca_options
62
- @options ||= begin
63
- path = Rails.root.join("config", "lca.yml").to_s
64
- if File.exist?(path)
65
- YAML.load(ERB.new(File.read(path)).result)
66
- else
67
- {
68
- table_name: "lca_models",
69
- jwt_secret: "",
70
- jwt_encryption: "HS256"
71
- }
72
- end
73
- end
74
- end
75
47
 
76
48
  def self.env
77
49
  @env ||= ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick @ Earthster
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-30 00:00:00.000000000 Z
11
+ date: 2021-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -25,33 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activestorage
28
+ name: active_tree
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '6.0'
33
+ version: 0.3.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '6.0'
41
- - !ruby/object:Gem::Dependency
42
- name: actiontext
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '6.0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '6.0'
40
+ version: 0.3.2
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: pg_ltree
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -97,14 +83,10 @@ files:
97
83
  - bin/console
98
84
  - bin/setup
99
85
  - lib/generators/lca/install_generator.rb
100
- - lib/generators/lca/templates/config.yml.tt
101
- - lib/generators/lca/templates/initializer.rb.tt
102
86
  - lib/generators/lca/templates/migration.rb.tt
103
87
  - lib/lca.rb
104
88
  - lib/lca/active_record.rb
105
- - lib/lca/builders/builder.rb
106
89
  - lib/lca/models/concerns/lcable.rb
107
- - lib/lca/models/concerns/statusable.rb
108
90
  - lib/lca/models/cycle.rb
109
91
  - lib/lca/models/cycle/activity.rb
110
92
  - lib/lca/models/cycle/product.rb
@@ -119,7 +101,6 @@ files:
119
101
  - lib/lca/models/impact/technosphere.rb
120
102
  - lib/lca/models/impact/technosphere/resource_availability.rb
121
103
  - lib/lca/models/impact_snapshot.rb
122
- - lib/lca/models/metadata.rb
123
104
  - lib/lca/models/model.rb
124
105
  - lib/lca/models/process.rb
125
106
  - lib/lca/models/process/raw_resource.rb
@@ -1,18 +0,0 @@
1
- # the main table will be called "lca_models"
2
- # partitions will be called "lca_models_X" where X is the owner object ID
3
- table_name: "lca_models"
4
-
5
- # create PG roles for postgrest: anon and owner-specific roles
6
- create_postgrest_roles: true
7
-
8
- # on owner removal, detach the partition but preserve the table and data, or destroy the partition and data
9
- # if you choose to detach and preserve, in order to avoid table name collisions, make sure owner IDs are not reused
10
- destroy_partition_on_owner_destroy: true
11
-
12
- # jwt secret required for postgrest role switching
13
- jwt_secret: "supersecret"
14
- jwt_encryption: "HS256"
15
-
16
- # suffix postgres roles with a random string
17
- # to avoid collisions between other LCA installations in other apps using same db server
18
- owner_role_suffix: "changeme"
@@ -1,17 +0,0 @@
1
- LCA_OPTIONS ||= begin
2
- path = Rails.root.join("config", "lca.yml").to_s
3
- if File.exist?(path)
4
- YAML.load( ERB.new(File.read(path)).result ).deep_symbolize_keys
5
- else
6
- {
7
- table_name: "lca_models",
8
- create_postgrest_roles: true,
9
- jwt_secret: "supersecret",
10
- jwt_encryption: "HS256",
11
- destroy_partition_on_owner_destroy: true,
12
- owner_role_suffix: "changeme"
13
- }
14
- end
15
- end.merge({
16
- database_user: Rails.application.config.database_configuration[ Rails.env ].deep_symbolize_keys[:username]
17
- })
@@ -1,3 +0,0 @@
1
- class Lca::Builder
2
-
3
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
- module Lca::Statusable
3
-
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- scope :active, -> { where(status: 1) }
8
- scope :inactive, -> { where(status: 0) }
9
- alias_method :enabled?, :active?
10
- alias_method :enable!, :active!
11
- alias_method :on!, :active!
12
- alias_method :disabled?, :inactive?
13
- alias_method :disable!, :inactive!
14
- alias_method :off!, :inactive!
15
- alias_method :toggle?, :toggle_status!
16
-
17
- before_create :set_default_status
18
- end
19
-
20
- def set_default_status
21
- self.status ||= 1
22
- end
23
-
24
- def toggle_status!
25
- if active?
26
- inactive!
27
- else
28
- active!
29
- end
30
- end
31
-
32
- def status?
33
- [:inactive, :active][ status ]
34
- end
35
-
36
- def active?
37
- status == 1
38
- end
39
- def inactive?
40
- status == 0
41
- end
42
-
43
- def active!
44
- self.update(status: 1)
45
- end
46
- def inactive!
47
- self.update(status: 0)
48
- end
49
- end
@@ -1,12 +0,0 @@
1
- class Lca::Metadata < ActiveRecord::Base
2
-
3
- belongs_to :model, polymorphic: true, required: true
4
-
5
- def self.table_name
6
- return "#{ ::LCA_OPTIONS[:table_name] }_metadata" if defined? ::LCA_OPTIONS
7
- return "lca_models_metadata"
8
- end
9
-
10
- validates_presence_of :key
11
-
12
- end