GithubHelp home page GithubHelp logo

erlangbureau / jamdb_oracle Goto Github PK

View Code? Open in Web Editor NEW
104.0 18.0 48.0 805 KB

Oracle Database driver for Erlang

License: MIT License

Makefile 0.02% Erlang 53.48% Elixir 46.50%
erlang oracle-database ecto-adapter

jamdb_oracle's Introduction

Jamdb.Oracle

Erlang driver and Ecto adapter for Oracle Database

Features

  • Using prepared statement functionality, the SQL statement you want to run is precompiled and stored in a database object, and you can run it as many times as required without compiling it every time it is run. If the data in the statement changes, you can use bind variables as placeholders for the data and then provide literal values at run time.

  • Using bind variables:

    {"insert into tabl values (:1)", [<<16#E7,16#99,16#BE>>]}

  • Using named parameters:

    {"insert into tabl values (:id, :dat)", [#{dat => {2023, 1, 1}, id => 1}]}

  • Calling stored procedure:

    {"begin proc(:1, :2, :3); end;", [1.0, 2.0, 3.0]}

  • Calling stored function:

    {"begin :1 := func(:2); end;", [{:out, :varchar}, "one hundred"]}

  • Using cursor variable:

    {"begin open :1 for select * from tabl where dat>:2; end;", [:cursor, {2016, 8, 1}]}

  • Using returning clause:

    {"insert into tabl values (tablid.nextval, sysdate) return id into :1", [{:out, :number}]}

  • Update batching:

    {:batch, "insert into tabl values (:1, :2, :3)", [[1, 2, 3],[4, 5, 6],[7, 8, 9]]}

  • Row prefetching:

    {:fetch, "select * from tabl where id>:1", [1]}

    {:fetch, cursor, row_format, last_row}

Options

Adapter options split in different categories described below. All options can be given via the repository configuration:

config :your_app, YourApp.Repo,
  ...

Connection options

  • :hostname - Server hostname (Name or IP address of the database server)
  • :port - Server port (Number of the port where the server listens for requests)
  • :database - Database (Database service name or SID with colon as prefix)
  • :username - Username (Name for the connecting user)
  • :password - User password (Password for the connecting user)
  • :parameters - Keyword list of connection parameters
  • :socket_options - Options to be given to the underlying socket
  • :timeout - The default timeout to use on queries, defaults to 15000

Pool options

  • :pool - The connection pool module, defaults to DBConnection.ConnectionPool
  • :pool_size - The size of the pool, defaults to 1
  • :idle_interval - The ping interval to validate an idle connection, defaults to 5000

Connection parameters

  • :autocommit - Mode that issued an automatic COMMIT operation
  • :fetch - Number of rows to fetch from the server
  • :sdu - Size of session data unit
  • :read_timeout - Read timeout while reading from the socket, defaults to 500
  • :role - Mode that is used in an internal logon
  • :prelim - Mode that is permitted when the database is down
  • :newpassword - User new password (Change password for the connecting user)
  • :description - Connect descriptor
  • :charset - Client character set, defaults to UTF-8

Output parameters

  • Calling stored procedure or function: [{:out, :number}, {:out, :varchar}]
  • Using returning clause: [{:out, :number}, {:out, :date}]
Oracle types Literal syntax in params
NUMBER,FLOAT,BINARY_FLOAT :number, :integer, :float, :decimal
CHAR, VARCHAR2, CLOB :varchar, :char, :clob, :string
NCHAR, NVARCHAR2, NCLOB :nvarchar, :nchar, :nclob
RAW, BLOB :raw, :blob, :binary, :hexstring
DATE :date
TIMESTAMP :timestamp
TIMESTAMP WITH TIME ZONE :timestamptz
SYS_REFCURSOR :cursor

Input parameters

Using query options: [in: [:number, :binary]]

Primitive types

The primitive types are:

Ecto types Oracle types Literal syntax in params
:id, :integer NUMBER (*,0), INTEGER 1, 2, 3
:float NUMBER,FLOAT,BINARY_FLOAT 1.0, 2.0, 3.0
:decimal NUMBER,FLOAT,BINARY_FLOAT Decimal
:string CHAR, VARCHAR2, CLOB "one hundred"
:string NCHAR, NVARCHAR2, NCLOB "百元", "万円"
:binary RAW, BLOB "E799BE" (base 16 encoded)
:binary RAW, BLOB <<0xE7,0x99,0xBE>> (option [in: [:binary])
:binary_id RAW, BLOB <<231,153,190, ...>> (option [in: [:binary_id])
:boolean CHAR, VARCHAR2, NUMBER true, false
:map CLOB, NCLOB %{"one" => 1, "hundred" => "百"}
:naive_datetime DATE, TIMESTAMP NaiveDateTime
:utc_datetime TIMESTAMP WITH TIME ZONE DateTime

Character sets

String in Elixir is UTF-8 encoded binary.

:us7ascii, :we8iso8859p1, :ee8iso8859p2, :nee8iso8859p4, :cl8iso8859p5, :ar8iso8859p6, :el8iso8859p7,:iw8iso8859p8, :we8iso8859p9, :ne8iso8859p10, :th8tisascii, :vn8mswin1258, :we8iso8859p15,:blt8iso8859p13, :ee8mswin1250, :cl8mswin1251, :el8mswin1253, :iw8mswin1255, :tr8mswin1254,:we8mswin1252, :blt8mswin1257, :ar8mswin1256

:ja16euc, :ja16sjis, :ja16euctilde,:ja16sjistilde,:ko16mswin949, :zhs16gbk, :zht32euc, :zht16big5, :zht16mswin950, :zht16hkscs

Examples

iex> Ecto.Adapters.SQL.query(YourApp.Repo, "select 1+:1,sysdate,rowid from dual where 1=:1 ", [1])
{:ok, %{num_rows: 1, rows: [[2, ~N[2016-08-01 13:14:15], "AAAACOAABAAAAWJAAA"]]}}

iex> row = [%Ecto.Query.Tagged{value: <<0xE7,0x99,0xBE>>, type: :binary}]
iex> Ecto.Adapters.SQL.query(YourApp.Repo, "insert into tabl values (:1)", row)

iex> row = [%Ecto.Query.Tagged{value: %{dat: {2023, 1, 1}, id: 1}, type: :map}]
iex> Ecto.Adapters.SQL.query(YourApp.Repo, "insert into tabl values (:id, :dat)", row)
    
iex> opts = [batch: true, in: [Ecto.UUID, :number]]
iex> row = [Ecto.UUID.bingenerate, 1]
iex> Ecto.Adapters.SQL.query(YourApp.Repo, "insert into tabl values (:1, :2)",
...> [row, row], opts)
    
iex> opts = [returning: false, out: [:integer]]
iex> row = [Date.utc_today]
iex> Ecto.Adapters.SQL.query(YourApp.Repo, "insert into tabl (dat) values (:1) return id into :2",
...> row, opts)

Using quoted identifiers:

defmodule YourApp.Users do
  use Ecto.Schema

  schema "\\"USERS\\"" do
    field :id, :integer
    field :uuid, :binary_id
    field :name, :string, source: :'"NAME"'
    field :namae, :string, source: :'"名まえ"'
  end

end

iex> YourApp.Repo.all(from(u in "\\"USERS\\"", select: u.'"NAME"', where: u.id == 1))

iex> YourApp.Repo.all(from(u in YourApp.Users, select: u.namae, where: u.id == 1))

iex> uuid = "601d74e4-a8d3-4b6e-8365-eddb4c893327"
iex> YourApp.Repo.all(from(u in YourApp.Users, select: u.name,
iex> where: u.uuid == type(^uuid, :binary_id)), [in: [:binary_id]])

Imagine you have this migration:

defmodule YourApp.Repo.Migrations.Users do
  use Ecto.Migration

  def change do
    create table(:users, comment: "users table") do
      add :name, :string, comment: "name column"
      add :namae, :string, national: true
      add :custom_id, :uuid
      timestamps()
    end
  end

end

To migrate you'd do it normally:

$ mix ecto.migrate

jamdb_oracle's People

Contributors

isaacsanders avatar kagux avatar kianmeng avatar kostiushkin avatar lemenkov avatar marocchino avatar ps-36 avatar sax avatar stalkermn avatar vstavskyi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jamdb_oracle's Issues

Failed to connect on Amazon RDS for Oracle

I tried to connect to Amazon RDS for Oracle, Oracle 11g 11.2.0.4
Bellow error ocured.

As a basic knowledge,In Amazon RDS, DBA is not published to user.

[error] Jamdb.Oracle (#PID<0.573.0>) failed to connect: ** (ErlangError) Erlang error: {{:badmatch, {:error, :socket, :timeout, {:oraclient, #Port<0.17282>, :disconnected, 1, :select, 15000, <<224, 248, 202, 2, 125, 166, 50, 216, 231, 51, 106, 149, 169, 101, 231, 44>>, 15, 8192, :undefined, :undefined, :undefined, [], [timeout: 15000, password: 'TIGER', user: 'SCOTT', port: 1521, host: '---', service_name: '*****'], :utf8, #PID<0.575.0>}}}, [{:jamdb_oracle, :init, 1, [file: 'src/jamdb_oracle.erl', line: 35]}, {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 365]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 333]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}

config/dev.exs

config :test, Test.Repo,
  adapter: Ecto.Adapters.Jamdb.Oracle,
  username: "SCOTT",
  password: "TIGER",
  database: "****",
  hostname: "hostaddr",
  port: 1521,
  pool_size: 3,
  timeout: 15000,

Server connections:
image

Schema -> OS User shifted?

ecto migration failed

Not support yet?

** (MatchError) no match of right hand side value: {:error, {Jamdb.Oracle, {'no such file or directory', 'Elixir.Jamdb.Oracle.app'}}}
    (ecto) lib/mix/ecto.ex:99: Mix.Ecto.ensure_started/2
    (ecto) lib/mix/tasks/ecto.migrate.ex:76: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
    (elixir) lib/enum.ex:675: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:675: Enum.each/2
    (mix) lib/mix/task.ex:301: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:75: Mix.CLI.run_task/2
    (elixir) lib/code.ex:376: Code.require_file/2
config :my_ebs, MyEbs.Repo,
  adapter: Ecto.Adapters.Jamdb.Oracle,
  username: "oracle",
  password: "password",
  database: "TEST",
  hostname: "10.40.10.16",
  pool_size: 2,
  port: 1521
defmodule MyEbs.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users) do
      add :username, :string
      add :password, :string
      timestamps()
    end
  end
end

Using Ecto.Adapters.SQL.Sandbox with savepoints

I'm trying to run exunit tests against a test oracle database. Here's my test.exs config:

{port, _} = Integer.parse(System.get_env("ORACLE_PORT"))
config :moble_ca, MobleCa.Repo,
  adapter: Ecto.Adapters.Jamdb.Oracle,
  database: System.get_env("ORACLE_PDB"),
  port: port,
  username: System.get_env("ORACLE_USR"),
  password: System.get_env("ORACLE_PWD"),
  hostname: "testdb",
  backoff_type: :exp,
  backoff_min: 20_000,
  pool: Ecto.Adapters.SQL.Sandbox

I ran my first test ok and it passed. I ran it again and it failed:

ORA-01086: savepoint 'TRAN' never established in this session or is invalid

15:52:40.267 [error] Jamdb.Oracle (#PID<0.262.0>) disconnected: ** (ErlangError) Erlang error: %{code: 1086, message: 'ORA-01086: savepoint \'TRAN\' never established in this session or is invalid\n'}
ORA-03137: TTC protocol internal error : [12209] [0] [] [] [] [] [] []

I think what's going on is my databases triggers conflict with using save points. My db schema is kind of inflexible. Is there a way to use the sandbox with a different strategy than savepoints?

(ArgumentError) cannot load `8634.0` as type :integer for field

Oracle EBS usually uses NUMBER as primary key or integer column, not NUMBER(n, 0). Changing type to :decimal doesn't work, either.

defmodule Todos.EBS.Item do
  use Ecto.Schema
  import Ecto.Changeset
  alias Todos.EBS.Item

  @primary_key {:inventory_item_id, :integer, []}
  @derive {Phoenix.Param, key: :inventory_item_id}
  schema "mtl_system_items_b" do
    field :segment1
    field :description
    field :organization_id, :integer
  end
end
iex(2)> OracleRepo.get!(Item, 8634)
[debug] QUERY ERROR source="mtl_system_items_b" db=4.3ms decode=0.1ms
SELECT m0.inventory_item_id, m0.segment1, m0.description, m0.organization_id FROM mtl_system_items_b m0 WHERE (m0.inventory_item_id = :1) [8634]
** (ArgumentError) cannot load `8634.0` as type :integer for field `inventory_item_id` in schema Todos.EBS.Item
    (ecto) lib/ecto/schema.ex:1493: Ecto.Schema.load!/5
    (ecto) lib/ecto/schema.ex:1441: Ecto.Schema.safe_load_zip/4
    (ecto) lib/ecto/schema.ex:1429: Ecto.Schema.__safe_load__/6
    (ecto) lib/ecto/repo/queryable.ex:275: Ecto.Repo.Queryable.process_source/6
    (ecto) lib/ecto/repo/queryable.ex:170: Ecto.Repo.Queryable.preprocess/5
    (elixir) lib/enum.ex:1255: Enum."-map/2-lists^map/1-0-"/2
    (jamdb_oracle) lib/jamdb_oracle.ex:189: DBConnection.Query.Jamdb.Oracle.Query.decode/3
    (db_connection) lib/db_connection.ex:1011: DBConnection.decode/6
    (jamdb_oracle) lib/jamdb_oracle_ecto.ex:118: Ecto.Adapters.Jamdb.Oracle.Connection.prepare_execute/5
    (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
    (ecto) lib/ecto/repo/queryable.ex:78: Ecto.Repo.Queryable.one!/4

Table MTL_SYSTEM_ITEMS_B DDL

CREATE TABLE MTL_SYSTEM_ITEMS_B (
	INVENTORY_ITEM_ID NUMBER,
	ORGANIZATION_ID NUMBER,
	LAST_UPDATE_DATE DATE,
	LAST_UPDATED_BY NUMBER,
	CREATION_DATE DATE,
	CREATED_BY NUMBER,
	LAST_UPDATE_LOGIN NUMBER,
	SUMMARY_FLAG VARCHAR2(1),
	ENABLED_FLAG VARCHAR2(1),
	START_DATE_ACTIVE DATE,
	END_DATE_ACTIVE DATE,
	DESCRIPTION VARCHAR2(240),
	BUYER_ID NUMBER(9,0),
	ACCOUNTING_RULE_ID NUMBER,
	INVOICING_RULE_ID NUMBER,
	SEGMENT1 VARCHAR2(40),

Why a string save into DB will have one more '0' ?

I have the code like this:
Coupons.create_coupon %{promotion_id: promotion_id, discount_amount: promotion.discount_amount, user_id: uid, status: "sss"}
to save coupon into DB,
But when I get the record from DB, I got this?
%AdminApiEx.Coupons.Coupon{meta: #Ecto.Schema.Metadata<:loaded, "coupons">,
balance: nil, code: nil, coupon_id: 25, coupon_type: nil, created_at: nil,
discount_amount: nil, expiration: nil, got_time: nil, order_id: nil,
printed: nil,
promotion: #Ecto.Association.NotLoaded,
promotion_id: 32, status: <<0, 115, 0, 115, 0, 115>>, used_time: nil,
user_id: 1}

why the "status" became <<0, 115, 0, 115, 0, 115>>, not "sss"?

Support for DISTINCT ON

There is currently no support for executing distinct on queries, as documented in Ecto under https://hexdocs.pm/ecto/Ecto.Query.html#distinct/3.

For example

MyApp.Marker |> distinct(:id) |> select([m], m.id) |> Repo.all

Generates SQL

SELECT DISTINCT m0.id FROM markers AS m0

Executing the same query with Postgrex, this SQL is generated

SELECT DISTINCT on (m0.id) m0.id FROM markers AS m0

Can I configure the adapter to log sql statements?

I'd like to have a debug log mode that would let me see all the sql that jamdb is running. I'm accessing this from Ecto. I'm not exactly sure if I need this configured in Ecto somewhere, but I kinda feel like it should be available at the adapter level.

Dep poison has invalid version ~> 2.2 or ~> 3.0

Erlang/OTP 21 [erts-10.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

$ rebar3 new app welcome_jambd_oracle
$ cd welcome_jambd_oracle
$ vim rebar3.config
$ cat rebar3.config
{erl_opts, [debug_info]}.
{deps, [{jamdb_oracle, "0.3.0"}]}.

{shell, [
% {config, "config/sys.config"},
{apps, [welcome_jambd_oracle]}
]}.
$ rebar3 compile
===> Verifying dependencies...
===> Fetching jamdb_oracle ({pkg,<<"jamdb_oracle">>,<<"0.3.0">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/jamdb_oracle-0.3.0.tar is up to date, reusing it
===> Fetching ecto_sql ({pkg,<<"ecto_sql">>,<<"3.0.3">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/ecto_sql-3.0.3.tar is up to date, reusing it
===> Fetching jose ({pkg,<<"jose">>,<<"1.8.4">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/jose-1.8.4.tar is up to date, reusing it
===> Fetching base64url ({pkg,<<"base64url">>,<<"0.0.1">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/base64url-0.0.1.tar is up to date, reusing it
===> Fetching db_connection ({pkg,<<"db_connection">>,<<"2.0.3">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/db_connection-2.0.3.tar is up to date, reusing it
===> Fetching ecto ({pkg,<<"ecto">>,<<"3.0.5">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/ecto-3.0.5.tar is up to date, reusing it
===> Fetching mariaex ({pkg,<<"mariaex">>,<<"0.9.1">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/mariaex-0.9.1.tar is up to date, reusing it
===> Fetching postgrex ({pkg,<<"postgrex">>,<<"0.14.1">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/postgrex-0.14.1.tar is up to date, reusing it
===> Fetching telemetry ({pkg,<<"telemetry">>,<<"0.2.0">>})
===> Version cached at /Users/francesco/.cache/rebar3/hex/hexpm/packages/telemetry-0.2.0.tar is up to date, reusing it
===> Dep poison has invalid version ~> 2.2 or ~> 3.0

welcome_jambd_oracle
edit welcome_jambd_oracle/rebar.config to add:

Oracle number(8, 2) and the value default 0, Ecto float parse error

schema:
@primary_key false
schema "members" do
field :userid, :integer, primary_key: true
field :useremail, :string
field :userpassword, :string
field :userregistereddate, Ecto.Date
field :user90dvalue, :float

Error bellow when query:

** (ArgumentError) cannot load 0 as type :float for :user90dvalue in schema HelloPhoenix.Member
and the Date type
** (ArgumentError) cannot load {{2017, 2, 7}, {16, 18, 31}} as type Ecto.Date for :update_date in schema HelloPhoenix.Member

Any help?

Unable to connect to local database

Hi,

I'm trying to use your adapter to connect to a local Oracle instance from an Elixir/Phoenix app. This is what I have in terms of configuration:

mix.exs:
defp deps do
[
...
{:jamdb_oracle, git: "https://github.com/erlangbureau/jamdb_oracle.git"},

repo.ex:
defmodule Hello.Repo do
use Ecto.Repo,
otp_app: :hello,
adapter: Ecto.Adapters.Jamdb.Oracle
end

dev.exs:
config :hello, Hello.Repo,
hostname: "localhost",
port: 1521,
database: "XE",
username: "cruz",
password: "farfan"

After running "mix ecto.create", I get:
** (Mix) The database for Hello.Repo couldn't be created: false

But I'm able to connect from a CLI with:
sqlplus cruz/farfan@//localhost:1521/XE

Any ideas what am I doing wrong?

Thank you,

Cruz

Ecto Schema construct (limit) doesn't seem to work!

defmodule MyProject.Report do
  use Ecto.Schema

  # @primary_key false
  @primary_key {:ACT_ID, :id, autogenerate: true}
  schema "ACTIVITY_REPORT_2017" do
    field(:CONTACT_ID, :integer)
  end
end

And the following Queries work:

  1. Raw Query
Ecto.Adapters.SQL.query(MyProject.Repo, "SELECT * FROM ACTIVITY_REPORT_2017 where ROWNUM < 2")
  1. get query
Repo.get(Report, 113607038)

But when I try to run query with limit, it doesn't work!!

iex(1)> Report |> limit(10) |>  Repo.all
ORA-00933: SQL command not properly ended


14:50:51.444 [debug] QUERY ERROR source="ACTIVITY_REPORT_2017" db=198.9ms
SELECT C0.ACT_ID, C0.CONTACT_ID FROM ACTIVITY_REPORT_2017 C0 FETCH NEXT 10 ROWS ONLY []
** (DBConnection.ConnectionError) %{code: 933, message: 'ORA-00933: SQL command not properly ended\n'}
    (jamdb_oracle) lib/jamdb_oracle_ecto.ex:166: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
    (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4

Connecting in Oracle 11g.

Hello! I trying to connect in Oracle 11g. Using iex -S mix, apparently it connects but soon afterwards I get this error message:

[error] Jamdb.Oracle (#PID <0.380.0>) failed to connect: ** (ErlangError) Erlang error: {{: badmatch, {: error,: socket,: timeout, {: oraclient, #Port <0.14572 >,: disconnected, 1,: select, 15000, '458CE7535768DF1423FE86A2F335BA81', 15,: undefined, [], [], [timeout: 15000, password: '*', user: '', port: 1521 , host: '10 .0.2.117 ', service_name:' *** ']}}}, [{: jamdb_oracle,: init, 1, [file:' src / jamdb_oracle.erl ', line: 37]}, {: init_it, 6, [file: 'gen_server.erl', line: 333]}, {: proc_lib, init_it, : init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}

What can be happening ??

Thank you.

** (ArgumentError) cannot load `340.0` as type :integer

When count the subquery meet type error.

count_customers=from( c in CountryGroup, left_join: cu in assoc(c, :customers), group_by: c.countrygroup_id, select: %{countrygroup_id: c.countrygroup_id, count: count(cu.customer_id) })

q = from c in CountryGroup,
join: counts in subquery(count_customers),
on: counts.countrygroup_id== c.countrygroup_id,
select_merge: %{count: counts.count},
where: like(fragment("upper(countrygroup_name)"), ^countrygroupname) and like(fragment("upper(countrygroup_city)"), ^countrygroupcity)

Repo.all q

error:
iex(10)> Repo.all q
[debug] QUERY ERROR source="country_groups" db=4.8ms decode=9.1ms
SELECT c0.countrygroup_id, c0.countrygroup_city, c0.countrygroup_name, c0.country_id, c0.sys_user_id, c0.inserted_at, c0.updated_at, s1.count FROM country_groups c0 JOIN (SELECT c0.countrygroup_id countrygroup_id, count(c1.customer_id) count FROM country_groups c0 LEFT JOIN country_group_customers c2 ON c2.country_group_id = c0.countrygroup_id LEFT JOIN customers c1 ON c2.customer_id = c1.customer_id GROUP BY c0.countrygroup_id) s1 ON s1.countrygroup_id = c0.countrygroup_id WHERE ((upper(countrygroup_name) LIKE :1) AND (upper(countrygroup_city) LIKE :2)) ["%%", "%%"]
** (ArgumentError) cannot load 340.0 as type :integer
(ecto) lib/ecto/repo/queryable.ex:320: Ecto.Repo.Queryable.load!/5
(ecto) lib/ecto/repo/queryable.ex:262: Ecto.Repo.Queryable.process/5
(ecto) lib/ecto/repo/queryable.ex:308: anonymous fn/5 in Ecto.Repo.Queryable.process_kv/5
(elixir) lib/enum.ex:1397: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(ecto) lib/ecto/repo/queryable.ex:242: Ecto.Repo.Queryable.process/5
(ecto) lib/ecto/repo/queryable.ex:194: Ecto.Repo.Queryable.process/5
(ecto) lib/ecto/repo/queryable.ex:174: Ecto.Repo.Queryable.preprocess/5
(elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
(jamdb_oracle) lib/jamdb_oracle.ex:188: DBConnection.Query.Jamdb.Oracle.Query.decode/3
(db_connection) lib/db_connection.ex:1019: DBConnection.decode/6
(jamdb_oracle) lib/jamdb_oracle_ecto.ex:152: Ecto.Adapters.Jamdb.Oracle.Connection.prepare_execute/5
(ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
(ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4

Seems like the issue met before.

Oracle connection error codes

First thank you for creating this. I'm currently setting it up in a phoenix app and was wondering if it was possible to return the oracle connection error code?

Sproatically gettting error from (jamdb_oracle) lib/jamdb_oracle_ecto.ex:135

We are occasionally getting this error/stack trace. There does not seem to be any predictable pattern to it.

  ** (exit) an exception was raised: ** (FunctionClauseError) no function clause matching in Logger.Utils.truncate_n/2 (logger) lib/logger/utils.ex:20: Logger.Utils.truncate_n(%Jamdb.Oracle.Query{statement: "SELECT p0.token, p0.web_user_id, p0.inserted_at FROM password_reset_tokens p0 WHERE (p0.token = :1)"}, 8031) (logger) lib/logger/utils.ex:49: Logger.Utils.truncate_n_list/3 (logger) lib/logger/utils.ex:16: Logger.Utils.truncate/2 (logger) lib/logger.ex:581: Logger.bare_log/3 (ecto) lib/ecto/log_entry.ex:42: Ecto.LogEntry.log/1 (db_connection) lib/db_connection.ex:1178: DBConnection.log/6 (jamdb_oracle) lib/jamdb_oracle_ecto.ex:135: Ecto.Adapters.Jamdb.Oracle.Connection.execute/4 (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6

We are using the latest version of JamDB Ecto and using Ecto version "2.2.7". Let me know if you need any additional information.

oracle login error

2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|recv|292|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_290:
<<>>
<<0,11,0,0,12,0,0,0,1,0,1>>
2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|recv|285|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_283:
<<>>
2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|handle_login_resp|161|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_161:
12
<<1,0,1>>
2016-03-22 22:32:10.932 [error] |Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|CRASH REPORT Process <0.76.0> with 0 neighbours exited with reason: no match of right hand value login_failed in jamdb_oracle:init/1 line 37 in gen_server:init_it/6 line 330
** exception error: no match of right hand side value {error,{{badmatch,login_failed},
[{jamdb_oracle,init,1,
[{file,"src/jamdb_oracle.erl"},{line,37}]},
{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,237}]}]}}

Can't seem to use schema prefix

So far, my schema has been the default schema for the user I login to oracle as. I've defined my modules like this:

defmodule MyApp.MyModel do
  @schema_prefix "web_ca"

  schema "table_name" do
    field :name, :string
  end
end

So far everything has worked well. However, now need to support multiple schemas. Re-reading the documentation on @schema_prefix, I'm not sure it's doing what I want it to do. The documentation says:

@schema_prefix - configures the schema prefix. Defaults to nil, which generates structs and queries without prefix. When set, the prefix will be used by every built struct and on queries where the current schema is used in from (and only from exclusively). If a schema is used as a join or part of an assoc, @schema_prefix won’t be obeyed. In PostgreSQL, the prefix is called “SCHEMA” (typically set via Postgres’ search_path). In MySQL the prefix points to databases.

With the proper logging, I see something like this when I try to insert:

INSERT INTO table_name (id,name) VALUES (:1,:2) [72, "bob"]

I expected it to show the prefix here, but it doesn't. Maybe the answer is that I need two Repos: one for each schema with different authentication for each. That way each repo would be using their default schema for the user they are logged in as.

Could not compile

Version: 0.3.0
Elixir version: Elixir 1.7.4 (compiled with Erlang/OTP 20)
Ecto version: 3.0.3

==> jamdb_oracle
Compiling 5 files (.erl)
src/jamdb_oracle.erl:54: Warning: erlang:get_stacktrace/0: deprecated; use the new try/catch syntax for retrieving the stack backtrace
Compiling 3 files (.ex)

== Compilation error in file lib/jamdb_oracle_ecto.ex ==
** (FunctionClauseError) no function clause matching in Keyword.fetch!/2

    The following arguments were given to Keyword.fetch!/2:

        # 1
        Jamdb.Oracle

        # 2
        :driver

    Attempted function clauses (showing 1 out of 1):

        def fetch!(keywords, key) when is_list(keywords) and is_atom(key)

    (elixir) lib/keyword.ex:383: Keyword.fetch!/2
    lib/jamdb_oracle_ecto.ex:113: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:126: :erl_eval.exprs/5
could not compile dependency :jamdb_oracle, "mix compile" failed. You can recompile this dependency with "mix deps.compile jamdb_oracle", update it with "mix deps.update jamdb_oracle" or clean it with "mix deps.clean jamdb_oracle"

crypto:rand_bytes -> crypto:strong_rand_bytes

Hi,

I tried to compile your jamdb_oracle erlang driver ( which very pleased me, because I was looking for it for a long time) but it ended with this error :-(

jamdb_oracle git:(master) ✗ make app
ERLC jamdb_oracle.erl jamdb_oracle_conn.erl jamdb_oracle_crypt.erl jamdb_oracle_tns_decoder.erl jamdb_oracle_tns_encoder.erl
compile: warnings being treated as errors
src/jamdb_oracle_crypt.erl:25: crypto:rand_bytes/1 is deprecated and will be removed in a future release; use crypto:strong_rand_bytes/1

Is there any reason why there is still crypto:rand_bytes instaead of crypto:strong_rand_bytes ?
I have modified jamdb_oracle_crypt.erl ( line 25 ) and it compiled without error, but I'm not sure about the reason crypto:rand_bytes is still in source code ?

Regards,

Pavel

PS: Thx, for your work.

Connection error without reason

I got an error every time I use to connect do my OracleDB.

Command: {:ok, conn} = Jamdb.Oracle.connect(hostname: "fqdn", port: 1521, database: "sid-name", username: "user", password: "secret", timeout: 15000)

leads to the following error: ** (EXIT from #PID<0.257.0>) shell process exited with reason: [timeout: 15000, password: 'secret', user: 'user', port: 1521, host: 'fqdn', service_name:'sid-name']

I also have to define port and timeout, because the default-values weren't used (got an error for missing parameters).

Oracle instantclient is installed and works properly.

Can't get anything out of the error-'description' above.

How to paging the records?

We know pagination in oracle by using ROWNUM, how to implement the pagination code when using this driver? could you kindly give an example?

Binary length should be considered in o5logon/4

Jamdb_oracle works fine in Linux oracle, but not in windows oracle.
Then I found this issue: the length of Rest1 may be less than 32, so the code(with "+") below may be the better choice.

-    Rest2 = crypto:block_encrypt(des_cbc, binary:part(Rest1,24,8), IVec, CliPass),
-    Data = binary:part(Rest2,24,8),
+    Rest2 = crypto:block_encrypt(des_cbc, binary:part(Rest1, size(Rest1)-8, 8), IVec, CliPass),
+    Data = binary:part(Rest2, size(Rest2)-8, 8),

Error "'ORA-01003: no statement parsed'"

I'm facing an issue where my repo stops working when there is a schema change on the DB.
Every single query after the schema change returns the following error:

** (exit) an exception was raised:
2018-12-19T15:31:53.374709+00:00 app[web.2]: ** (DBConnection.ConnectionError) 'ORA-01003: no statement parsed\n'
2018-12-19T15:31:53.374710+00:00 app[web.2]: (ecto_sql) lib/ecto/adapters/sql.ex:595: Ecto.Adapters.SQL.raise_sql_call_error/1
2018-12-19T15:31:53.374712+00:00 app[web.2]: (ecto_sql) lib/ecto/adapters/sql.ex:528: Ecto.Adapters.SQL.execute/5
2018-12-19T15:31:53.374713+00:00 app[web.2]: (ecto) lib/ecto/repo/queryable.ex:147: Ecto.Repo.Queryable.execute/4
2018-12-19T15:31:53.374715+00:00 app[web.2]: (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3

And it is only fixed after all the connections are restarted (As i'm on heroku, the fix is to restart the processes.)

The question is, should the driver do something in this case?
Should I manually monitor for this kind of errors and force a repo stop and start?

Do you have any prior knowledge of this?

How to slow down re-connect attempts?

First of all thanks for creating jamdb_oracle. I've started to look into it for a Phoenix project with a potential use in a productive environment.

While I was testing I realised that when database is not reachable the driver is constantly trying to re-connect within a very short time.

The underlying DBConnection component has the concept of backoff_type (see here). Wondering if it is possible to pass parameter via the initial connection configuration in Phoenix.

I was thinking along these lines but that was not working:

# ./config/dev.exs
config :screening, Screening.Repo,
  adapter: Ecto.Adapters.Jamdb.Oracle,
  hostname: "myhost.domain.com",
  port: 1521,
  database: "mydatabase",
  username: "a_user",
  password: "secret_password",
  parameters: [{:backoff_type, :exp}]. # or :rand or :exp_rand (which should be the default)

What I get is a lot of these errors and I'd like to slow down the connection attempts:

# console output
...
[error] Jamdb.Oracle (#PID<0.10491.0>) failed to connect: ** (ErlangError) Erlang error: {{:badmatch, {:error, :socket, :nxdomain}}, [{:jamdb_oracle, :init, 1, [file: 'src/jamdb_oracle.erl', line: 35]}, {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 374]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 342]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}
...

And yes, I am new to Elixir and the Phoenix Framework.

I am using Elixir 1.6.6 (compiled with OTP 20) and Phoenix v1.3.2

Thanks for every hint and help.

definition of encode_token/2

Hi,

In line 294 of jamdb_oracle_tns_encoder.erl, there is a call "encode_token(Data, <<?TTI_RXD>>)", but I can't find the proper encode_tokern/2 clause to execute:

encode_token([], Acc) -> Acc;

encode_token([Data|Rest], Acc) -> encode_token(Rest, <<Acc/binary, (encode_token(rxd, Data))/binary>>);

encode_token(rxd, Data) when is_list(Data) -> encode_chr(Data);

encode_token(rxd, Data) when is_binary(Data) -> encode_chr(unicode:characters_to_binary(Data, utf8, utf16));

encode_token(rxd, Data) when is_number(Data) -> encode_len(encode_number(Data));

encode_token(rxd, Data) when is_tuple(Data) -> encode_len(encode_date(Data));

encode_token(rxd, cursor) -> <<1,0>>;

encode_token(rxd, null) -> <<0>>;

encode_token(oac, Data) when is_list(Data) -> encode_token(oac, ?TNS_TYPE_VARCHAR, 4000, 16, ?UTF8_CHARSET, 0);

encode_token(oac, Data) when is_binary(Data) -> encode_token(oac, ?TNS_TYPE_VARCHAR, 4000, 16, ?AL16UTF16_CHARSET, 0);

encode_token(oac, Data) when is_number(Data) -> encode_token(oac, ?TNS_TYPE_NUMBER, 22, 0, 0, 0);

encode_token(oac, {{_Year,_Mon,_Day}, {_Hour,_Min,_Sec,_Ms}}) -> encode_token(oac, ?TNS_TYPE_TIMESTAMP, 11, 0, 0, 0);

encode_token(oac, {{_Year,_Mon,_Day}, {_Hour,_Min,_Sec,_Ms}, _}) -> encode_token(oac, ?TNS_TYPE_TIMESTAMPTZ, 13, 0, 0, 0);

encode_token(oac, Data) when is_tuple(Data) -> encode_token(oac, ?TNS_TYPE_DATE, 7, 0, 0, 0);

encode_token(oac, cursor) -> encode_token(oac, ?TNS_TYPE_REFCURSOR, 1, 0, ?UTF8_CHARSET, 0);

encode_token(oac, null) -> encode_token(oac, []).

Incompatible with Ecto 2.2

Hey,

Thanks for building this library!

Ecto 2.2 introduced breaking changes to your library.

== Compilation error in file lib/jamdb_oracle_query.ex ==
** (CompileError) lib/jamdb_oracle_query.ex:287: unknown key :fields for struct Ecto.SubQuery
    lib/jamdb_oracle_query.ex:287: (module)

'ORA-01006: bind variable does not exist' when preloading has_many through relation with multiple records

Is this a bug within the generated sql or am I doing something wrong?

defmodule PlonquoApi.Schemas.Activity do
    use Ecto.Schema
    import Ecto.Changeset
    alias PlonquoApi.Schemas.Activity

   # @primary_key{:id, :integer, autogenerate: false}
    schema "TIMP.activities" do
      field :activity_type, :string

      has_many :activity_assets, PlonquoApi.Schemas.ActivityAsset
      has_many :assets, through: [:activity_assets,:asset]
    end

    @doc false
    def changeset(%Activity{} = activity, attrs) do
      activity
      |> cast(attrs, [])
      |> validate_required([])
    end
  end
defmodule PlonquoApi.Schemas.ActivityAsset do
    use Ecto.Schema
    import Ecto.Changeset
    alias PlonquoApi.Schemas.ActivityAsset

    @primary_key{:id, :integer, autogenerate: false}
    schema "TIMP.activity_assets" do
      field :created_at, :utc_datetime
      field :updated_at, :utc_datetime
      field :position_before, :integer
      field :position_after, :integer
      field :position, :integer
      field :position_code, :string
      field :sort_order, :integer
      field :real_start, :utc_datetime
      field :real_end, :utc_datetime
      field :activity_class, :string
      field :activity_type, :string

      belongs_to :activity, PlonquoApi.Schemas.Activity
      belongs_to :asset, PlonquoApi.Schemas.Asset, references: :id, type: :string

    end

    @doc false
    def changeset(%ActivityAsset{} = activity_asset, attrs) do
      activity_asset
      |> cast(attrs, [])
      |> validate_required([])
    end
  end
defmodule PlonquoApi.Schemas.Asset do
    use Ecto.Schema
    import Ecto.Query
    import Ecto.Changeset
    alias PlonquoApi.Schemas.{Asset,Activity}

    @primary_key{:id, :string, autogenerate: false}
    schema "TIMP.assets" do
      field :created_at, :utc_datetime
      field :updated_at, :utc_datetime
      field :implementation_id, :integer
      field :implementation_type, :string
      field :asset_nr, :string
      field :company_id, :integer

    end

    @doc false
    def changeset(%Asset{} = asset, attrs) do
      asset
      |> cast(attrs, [])
      |> validate_required([])
    end
  end

When trying to preload the assets belonging to activity through the ActivityAsset association:

a = PlonquoApi.Repo.get(PlonquoApi.Schemas.Activity,229852) |> PlonquoApi.Repo.preload([:assets])

It returns an oracle error

[debug] QUERY ERROR source="TIMP.assets" db=55.9ms queue=0.1ms
SELECT T0.id, T0.created_at, T0.updated_at, T0.implementation_id, T0.implementation_type, T0.asset_nr, T0.company_id, T0.id FROM TIMP.assets T0 WHERE (T0.id = ANY(:1)) ["locomotive_100002", "locomotive_7972", "person_10021"]
** (DBConnection.ConnectionError) %{code: 1006, message: 'ORA-01006: bind variable does not exist\n'}
    (jamdb_oracle) lib/jamdb_oracle_ecto.ex:165: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
    (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:448: Ecto.Adapters.SQL.sql_call!/6
    (ecto) lib/ecto/adapters/sql.ex:420: Ecto.Adapters.SQL.do_execute/6
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
    (elixir) lib/enum.ex:1273: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1273: Enum."-map/2-lists^map/1-0-"/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:438: :erl_eval.expr/5
    (iex) lib/iex/evaluator.ex:231: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:212: IEx.Evaluator.do_eval/3

Database credentials shown in error log

I noticed that sometimes when the connection to the database timeouts all the database credentials are shown in the error log.
This could form a security risk.

[error] Jamdb.Oracle (#PID<0.559.0>) failed to connect: ** (ErlangError) Erlang error: [timeout: 15000, password: '------', user: '------', port: ---, host: '------', service_name: '------]

oracle login error

2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|recv|292|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_290:
<<>>
<<0,11,0,0,12,0,0,0,1,0,1>>
2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|recv|285|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_283:
<<>>
2016-03-22 22:32:10.931 [debug] |jamdb_oracle|jamdb_oracle_conn|handle_login_resp|161|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|_161:
12
<<1,0,1>>
2016-03-22 22:32:10.932 [error] |Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|Undefined|CRASH REPORT Process <0.76.0> with 0 neighbours exited with reason: no match of right hand value login_failed in jamdb_oracle:init/1 line 37 in gen_server:init_it/6 line 330
** exception error: no match of right hand side value {error,{{badmatch,login_failed},
[{jamdb_oracle,init,1,
[{file,"src/jamdb_oracle.erl"},{line,37}]},
{gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,237}]}]}}

crc32 error when there is unicode in sql.

Repo.all(from(c in Coupon, where: c.status=="你好"))
[debug] QUERY ERROR source="coupons" db=126.3ms
SELECT c0.coupon_id, c0.balance, c0.code, c0.coupon_type, c0.discount_amount, c0.order_id, c0.printed, c0.status, c0.user_id, c0.got_time, c0.used_time, c0.expiration, c0.created_at, c0.promotion_id FROM coupons c0 WHERE (c0.status = '你好') []
** (DBConnection.ConnectionError) [{:erlang, :crc32, [[83, 69, 76, 69, 67, 84, 32, 99, 48, 46, 99, 111, 117, 112, 111, 110, 95, 105, 100, 44, 32, 99, 48, 46, 98, 97, 108, 97, 110, 99, 101, 44, 32, 99, 48, 46, 99, 111, 100, 101, 44, 32, 99, 48, 46, 99, ...]], []}, {:jamdb_oracle_conn, :get_param, 2, [file: 'src/jamdb_oracle_conn.erl', line: 305]}, {:jamdb_oracle_conn, :get_param, 2, [file: 'src/jamdb_oracle_conn.erl', line: 316]}, {:jamdb_oracle_conn, :send_req, 3, [file: 'src/jamdb_oracle_conn.erl', line: 228]}, {:jamdb_oracle_conn, :sql_query, 3, [file: 'src/jamdb_oracle_conn.erl', line: 110]}, {:jamdb_oracle, :handle_call, 3, [file: 'src/jamdb_oracle.erl', line: 45]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 636]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 665]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]
(jamdb_oracle) lib/jamdb_oracle_ecto.ex:165: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
(ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
(ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4

"in" operator does not work when using an Array variable in sql

Environment

Elixir version (elixir -v) : 1.5.0
Database and version (PostgreSQL 9.4, MongoDB 3.2, etc.): PostgreSQL: 9.4
Ecto version (mix deps): 2.2.6
Database adapter and version (mix deps): Ecto.Adapters.Postgres,
Operating system: Mac Sierra
Current behavior

When I use a ^variable in "where", the query sql is became "= ANY($1)"
iex(6)> ids=[1,2]
[1, 2]
iex(7)> from(p in Promotion, select: p, where: p.promotion_id in ^ids) |> Repo.all
[debug] QUERY OK source="promotions" db=2.2ms queue=0.1ms
SELECT p0."id", p0."name", p0."promotion_id", p0."status", p0."inserted_at", p0."updated_at" FROM "promotions" AS p0 WHERE (p0."promotion_id" = ANY($1)) [[1, 2]]

And if I wrote the array in query directly, it works.
from(p in Promotion, select: p, where: p.promotion_id in [1, 2]) |> Repo.all
[debug] QUERY OK source="promotions" db=1.4ms
SELECT p0."id", p0."name", p0."promotion_id", p0."status", p0."inserted_at", p0."updated_at" FROM "promotions" AS p0 WHERE (p0."promotion_id" IN (1,2)) []

And it works on ECTO version of 2.1.4

Expected behavior

Cast the "where: p.promotion_id in ^ids" to the right sql.

can not be config to run mix ecto.migrate

mix.exs
def application do
[mod: {HelloPhoenix, []},
applications: [:phoenix, :phoenix_pubsub, :phoenix_html, :cowboy, :logger, :gettext, :jamdb_oracle,
:phoenix_ecto]]
end
defp deps do
[{:phoenix, "> 1.2.1"},
{:phoenix_pubsub, "
> 1.0"},
{:phoenix_ecto, "> 3.0"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "
> 2.6"},
{:phoenix_live_reload, "> 1.0", only: :dev},
{:gettext, "
> 0.11"},
{:jamdb_oracle, "> 0.0.5"},
{:cowboy, "
> 1.0"}]
end

dev.exs
config :hello_phoenix, HelloPhoenix.Repo,
name: HelloPhoenix.Repo,
adapter: Ecto.Adapters.Jamdb.Oracle,
port: 1521,
username: "username",
password: "password",
database: ":devdb1",
hostname: "mydblocal.com",
pool_size: 10,
pool: DBConnection.Poolboy

errors when run mix ecto.migrate
Generated hello_phoenix app
** (MatchError) no match of right hand side value: {:error, {Jamdb.Oracle, {'no such file or directory', 'Elixir.Jamdb.Oracle.app'}}}
(ecto) lib/mix/ecto.ex:84: Mix.Ecto.ensure_started/2
(ecto) lib/mix/tasks/ecto.migrate.ex:72: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
(elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:645: Enum.each/2
(mix) lib/mix/task.ex:294: Mix.Task.run_task/3
(mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2
(elixir) lib/code.ex:370: Code.require_file/2

any help?

don't support nvarchar2

The nvarchar2-type-values can't be selected correctly, while varchar2-type-values correct

`:fetch` parameter raises 'ORA-01002: fetch out of sequence'

Hey,

I've tried using :fetch parameter, but query returns an error:

11:53:36.011 [debug] QUERY ERROR source="cptra_functional_groups" db=417.0ms
SELECT c0.fn_group_id, c0.short_name FROM cptra_functional_groups c0 []

11:53:36.024 [error] #PID<0.452.0> running Milo.Web terminated
Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
    ** (DBConnection.ConnectionError) %{code: 1002, message: 'ORA-01002: fetch out of sequence\n'}
        (jamdb_oracle) lib/jamdb_oracle_ecto.ex:141: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
        (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
        (ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.execute_and_cache/7
        (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
        (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
        (milo) lib/milo/category.ex:16: anonymous fn/1 in Milo.Category.get_short_names_indexed_by_id/0
        (cachex) lib/cachex/util.ex:77: Cachex.Util.get_fallback/4
        (cachex) lib/cachex/actions/get.ex:42: Cachex.Actions.Get.handle_record/4

Error decoding too long fields

Hi,

I've got this error when querying a big varchar column constructed from a wm_concat() function (temporary table).

** (DBConnection.ConnectionError) [{:jamdb_oracle_tns_decoder, :decode_chr, 2, [file: 'src/jamdb_oracle_tns_decoder.erl', line: 502]}, {:jamdb_oracle_tns_decoder, :decode_data, 2, [file: 'src/jamdb_oracle_tns_decoder.erl', line: 400]}, {:jamdb_oracle_tns_decoder, :decode_rxd, 6, [file: 'src/jamdb_oracle_tns_decoder.erl', line: 342]}, {:jamdb_oracle_tns_decoder, :decode_token, 3, [file: 'src/jamdb_oracle_tns_decoder.erl', line: 182]}, {:jamdb_oracle_conn, :handle_resp, 4, [file: 'src/jamdb_oracle_conn.erl', line: 232]}, {:jamdb_oracle, :handle_call, 3, [file: 'src/jamdb_oracle.erl', line: 43]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 661]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 690]}]
(jamdb_oracle) lib/jamdb_oracle_ecto.ex:175: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
(ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
(fetch_sil) lib/fetch_sil.ex:18: FetchSil.hello/0

There seems to be an invalid character in my data ? I can query it with Squirrel or SQLDeveloper without issues. When I do an aggressive substr() on the field (truncate the varchar at 50), thus probably eliminating the unwanted char, I don't suffer from the issue anymore.

Cheers / thanx a lot for this library.

Error using Repo.stream

Hi,

I don't know if this is an error or an unimplemented feature.

I'm using jamdb_oracle 0.0.10 with ecto 2.2.6, when I try to use stream I get two different ORA errors.

Using query I don't have any problem.

Method:

...
  def stream do
    Repo.transaction(
      fn ->
        Application.get_env(:oferta_data_pump, :query_local)
        |> Repo.stream
        |> Enum.to_list
      end
    )
  end
...

Errors:

iex(2)> OfertaDataPump.stream

16:31:58.453 [debug] QUERY OK db=2.0ms
begin []

16:31:58.474 [debug] QUERY OK source="select * from SYSCATALOG\n" db=0.0ms
SELECT &(0) FROM select * from SYSCATALOG
 s0 []
ORA-01745: invalid host/bind variable name


16:31:58.480 [debug] QUERY ERROR source="select * from SYSCATALOG\n" db=5.4ms
SELECT &(0) FROM select * from SYSCATALOG
 s0 []

16:31:58.480 [debug] QUERY OK source="select * from SYSCATALOG\n" db=0.0ms
SELECT &(0) FROM select * from SYSCATALOG
 s0 []
ORA-01086: savepoint 'TRAN' never established in this session or is invalid


16:31:58.483 [debug] QUERY ERROR db=3.2ms
rollback []
** (ArgumentError) raise/1 expects a module name, string or exception as the first argument, got: %{code: 1086, message: 'ORA-01086: savepoint \'TRAN\' never established in this session or is invalid\n'}
    (db_connection) lib/db_connection.ex:794: DBConnection.transaction/3

Set connection encoding

I have an OracleDB with a very bad encoding (I can't change). In Ruby I can set a paramter in the driver (OCI8.encoding = 'Windows-1252'). Would be great if this worked for the Elixir-driver too.

batch insert could not handle maps

It failed when I tried to exec a batch insert with a list of maps like this:

jamdb_oracle:sql_query(Conn, {batch, "insert .... values (:field1, :field2)", [#{field1 =>1, field2 =>2}, #{field1 =>1, field2 =>2}]}).

Maybe we should change jamdb_oracle/src/jamdb_oracle_conn.erl:230 to

send_req(exec, State, {Query, get_param(Data, Bind, []), [get_param(Data, B, []) || B <- Batch]});

thank you.

send_req(exec, State, {Query, Bind, Batch}) when is_map(Bind) ->
Data = lists:filtermap(fun(L) -> case string:chr(L, $:) of 0 -> false; I -> {true, lists:nthtail(I, L)} end end,
string:tokens(Query," \t;,)")),
send_req(exec, State, {Query, get_param(Data, Bind, []), Batch});
send_req(exec, #oraclient{fetch=Fetch,cursors=Cursors,seq=Task} = State, {Query, Bind, Batch}) ->
{Type, Fetch2} = get_param(type, {lists:nth(1, string:tokens(string:to_upper(Query)," \t")), [B || {out, B} <- Bind], Fetch}),
DefCol = get_param(defcols, {Query, Cursors}),
{LCursor, Cursor} = get_param(defcols, DefCol),
Pig = if Cursor > 0 -> get_record(pig, [], {?TTI_CANA, [Cursor]}, Task); true -> <<>> end,
Pig2 = if Cursor > 0 -> get_record(pig, [], {?TTI_OCCA, [Cursor]}, Task); true -> <<>> end,
Data = get_record(exec, State#oraclient{type=Type,fetch=Fetch2}, {LCursor, if LCursor =:= 0 -> Query; true -> [] end,
[get_param(data, B) || B <- Bind], Batch, []}, Task),
send(State#oraclient{type=Type,defcols=DefCol,params=[get_param(format, B) || B <- Bind]},
?TNS_DATA, <<Pig/binary, Pig2/binary, Data/binary>>).

Oracle Client

Hi, Is this driver works without Oracle Client or it need to be installed for this driver to work. JDBC or ODP.Net Managed driver work without Oracle Client, so is this driver depend on it or not.

Thanks

Error: ORA-01000: maximum open cursors exceeded

I'm a new oracle user, I get lots of errors of ORA-01000: maximum open cursors exceeded while query in a loop, and I learn some knowledge about this cursors, it says the cursors should be closed, so I want to kown , if there is a API to release the cursors ? Thanks!

Cursor out parameter example request.

I would really appreciate an example with a cursor out parameter in a stored procedure.

I am not able to translate to working elixir code the test fragment at: test/jamdb_oracle_SUITE.erl
with_input_and_output_params.

If a procedure has signature:

   procedure myprocedure(someData varchar2, aSqlErrM out varchar, aRows out sys_refcursor )

what code is needed?

    conn_opts = Application.get_env(:myapp, :conn_opts)
    {:ok, pid} = Jamdb.Oracle.connect(conn_opts)
    
    sql = "BEGIN MYPKG.MYPROCEDURE(:1, :2, :3); END;"
           |> to_charlist
    data = "my_input_value"
         |> to_charlist
    Jamdb.Oracle.query(pid, sql, %{
      :"1" => {:in, data},
      :"2" => {:out, "0"},
      :"3" => {:out, :cursor}
    })

{:error,
 [
   {:jamdb_oracle_tns_decoder, :decode_ub4, 1,
    [file: 'src/jamdb_oracle_tns_decoder.erl', line: 481]},
   {:jamdb_oracle_tns_decoder, :decode_token, 2,
    [file: 'src/jamdb_oracle_tns_decoder.erl', line: 80]},
   {:jamdb_oracle_tns_decoder, :decode_token, 3,
    [file: 'src/jamdb_oracle_tns_decoder.erl', line: 126]},
   {:jamdb_oracle_tns_decoder, :decode_token, 3,
    [file: 'src/jamdb_oracle_tns_decoder.erl', line: 111]},
   {:jamdb_oracle_tns_decoder, :decode_token, 3,
    [file: 'src/jamdb_oracle_tns_decoder.erl', line: 169]},
   {:jamdb_oracle_conn, :handle_resp, 4,
    [file: 'src/jamdb_oracle_conn.erl', line: 232]},
   {:jamdb_oracle, :handle_call, 3, [file: 'src/jamdb_oracle.erl', line: 43]},
   {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 661]}
 ], #PID<0.327.0>}

VARCHAR decoding error

Hey,

I'm getting an error selecting a row that has a VARCHAR (DataType is 1) field with following value:

<<254,64,104,116,116,112,58,47,47,99,97,112,116,101,114,114,97,46,99,111,109,47,101,120,116,101,114,110,97,108,95,99,108,105,99,107,47,99,97,116,101,103,111,114,121,45,117,112,103,114,97,100,101,100,45,118,105,115,105,116,45,119,101,98,115,105,64,116,101,45,98,117,116,116,111,110,47,49,47,50,48,52,52,55,48,50,47,49,52,51,53,48,48,47,105,116,112,114,111,106,47,97,72,82,48,99,68,111,118,76,50,49,114,100,67,53,106,98,71,70,121,97,88,112,108,98,105,53,106,98,50,64,48,118,99,72,74,118,97,109,86,106,100,67,49,116,89,87,53,104,90,50,86,116,90,87,53,48,76,87,90,118,99,105,49,112,100,67,53,111,100,71,49,115,80,51,78,118,100,88,74,106,90,84,49,104,90,109,90,112,98,71,108,104,100,71,64,85,109,98,87,86,107,97,88,86,116,80,87,78,104,99,72,82,108,99,110,74,104,74,109,78,104,98,88,66,104,97,87,100,117,83,85,81,57,97,88,82,122,90,88,74,50,97,87,78,108,74,109,78,121,90,87,70,48,97,88,90,108,80,88,64,66,121,98,50,112,108,89,51,81,116,98,87,70,117,89,87,100,108,98,87,86,117,100,67,49,109,98,51,73,116,97,88,81,109,97,50,86,53,100,50,57,121,90,68,49,117,89,83,90,49,100,71,49,102,99,50,57,49,99,109,78,108,80,87,64,70,109,90,109,108,115,97,87,70,48,90,83,90,49,100,71,49,102,98,87,86,107,97,88,86,116,80,87,78,104,99,72,82,108,99,110,74,104,74,110,86,48,98,86,57,106,89,87,49,119,89,87,108,110,98,106,49,112,100,72,78,108,99,110,64,90,112,89,50,85,109,100,88,82,116,88,50,78,118,98,110,82,108,98,110,81,57,99,72,74,118,97,109,86,106,100,67,49,116,89,87,53,104,90,50,86,116,90,87,53,48,76,87,90,118,99,105,49,112,100,67,90,49,100,71,49,102,100,71,64,86,121,98,84,49,117,89,87,104,48,100,72,65,54,76,121,57,116,97,51,81,117,89,50,120,104,99,109,108,54,90,87,52,117,89,50,57,116,76,51,66,121,98,50,112,108,89,51,81,116,98,87,70,117,89,87,100,108,98,87,86,117,100,67,64,49,109,98,51,73,116,97,88,81,117,97,72,82,116,98,68,57,122,98,51,86,121,89,50,85,57,89,87,90,109,97,87,120,112,89,88,82,108,74,109,49,108,90,71,108,49,98,84,49,106,89,88,66,48,90,88,74,121,89,83,90,106,89,87,64,49,119,89,87,108,110,98,107,108,69,80,87,108,48,99,50,86,121,100,109,108,106,90,83,90,106,99,109,86,104,100,71,108,50,90,84,49,119,99,109,57,113,90,87,78,48,76,87,49,104,98,109,70,110,90,87,49,108,98,110,81,116,90,109,64,57,121,76,87,108,48,76,87,90,121,90,87,86,48,99,109,108,104,98,67,90,114,90,88,108,51,98,51,74,107,80,87,53,104,74,110,86,48,98,86,57,122,98,51,86,121,89,50,85,57,89,87,90,109,97,87,120,112,89,88,82,108,74,110,64,86,48,98,86,57,116,90,87,82,112,100,87,48,57,89,50,70,119>>

And here's the error log

** (exit) an exception was raised:                                                                                                                                                                                                                                                  ** (DBConnection.ConnectionError) [{:jamdb_oracle_tns_decoder, :decode_chr, 2, [file: 'jamdb_oracle_tns_decoder.erl', line: 504]}, {:jamdb_oracle_tns_decoder, :decode_data, 2, [file: 'jamdb_oracle_tns_decoder.erl', line: 399]}, {:jamdb_oracle_tns_decoder, :decode_rxd, 6, [file: 'jamdb_oracle_tns_decoder.erl', line: 336]}, {:jamdb_oracle_tns_decoder, :decode_token, 3, [file: 'jamdb_oracle_tns_decoder.erl', line: 179]}]                                                                                                                               (jamdb_oracle) lib/jamdb_oracle_ecto.ex:141: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1                                                                                                                                                                                     (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6                                                                                                                                                                                                               (milo) lib/milo/web.ex:14: anonymous fn/1 in Milo.Web.do_match/4                                                                                                                                                                                                                (milo) lib/milo/web.ex:1: Milo.Web.plug_builder_call/2                                                                                                                                                                                                                          (milo) lib/plug/error_handler.ex:64: Milo.Web.call/2                                                                                                                                                                                                                            (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /milo/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

I'm trying to narrow down the issue and will update this issue if I find something.

Can not login in with right user info

I get an error ORA-01017: invalid username/password; logon denied
But, acctually I put the right username and password(I can login in with DBeaver)
With debugging , I find AUTH_VFR_DATA return undefined ...
here is oracle version info

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE	11.2.0.4.0	Production"
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

and I also use wireshark get this when connect with jamdb_oracle

_008

and connect with other tool(successful)

_009

Is there something wrong?

DBConnection.ConnectionError :token

I'm getting this stack trace in production of my phoenix app:

** (exit) an exception was raised:
    ** (DBConnection.ConnectionError) :token
        (jamdb_oracle) lib/jamdb_oracle_ecto.ex:166: Ecto.Adapters.Jamdb.Oracle.Connection.error!/1
        (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
        (client_compass) lib/client_compass/repo.ex:13: ClientCompass.Repo.nextval/1
        (client_compass) lib/web_ca/odometer_reading.ex:28: WebCa.OdometerReading.changeset/1
        (client_compass) lib/client_compass_web/controllers/odo_readings_controller.ex:64: ClientCompassWeb.OdoReadingsController.create/2

I've implemented nextval on my Repo like so:

  def nextval(sequence) do
    case query("SELECT WEB_CA.#{sequence}.nextval from dual") do
      {:ok, %{columns: ["NEXTVAL"], num_rows: 1, rows: [[next_id]]}} -> next_id
    end
  end

All of my Ecto modules have their own sequence and call nextval to get the unique primary key before inserting. We've written tests around this and it behaves reliably. We've used this in production with jamdb v0.1.0 with no errors. After upgrading to jamdb v0.1.1, we have intermittent errors as above. It's hard to describe the frequency as I don't have hard statistics. My estimation at this point is we're getting the above error about 1 out of 50 calls. I have one user who triggered the error, re-submitted and triggered the error again, then re-submitted a third time and it worked fine.

This piece of our code hasn't changed, yet we're seeing these new errors. We're looking for help figuring out how to work on this.

rebar.config is missing by execute mix deps.get

Hi I'm using elixir 1.2.5 and erlang 18.
my project's mix.exs as follows.

defmodule Hoge.Mixfile do
  use Mix.Project
  def application do
    [mod: {Hoge, []},
     applications: [
       :jamdb_oracle
     ]
    ]
  end
  defp deps do
    [
      {:jamdb_oracle, "~> 0.0.1"}
   ]
  end
end

then I execute mix deps.get,mix compile and got error.

Could not compile :jamdb_oracle, no "mix.exs", "rebar.config" or "Makefile" (pass :compile as an option to customize compilation, set it to "false" to do nothing)

in my deps/jamdb_oracle dir, only some directory are avaliable.
please upload rebar.config to hex.pm, thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.