Class: PeaClient

Inherits:
Object
  • Object
show all
Defined in:
lib/pea_client.rb

Constant Summary collapse

@@end_pack =
"dipsjbiemg"

Instance Method Summary collapse

Constructor Details

#initialize(ip_adress, partition_name, port, username, password, id_client, online_version, retrieve_statistics) ⇒ PeaClient

Initialize a new instance of the PeaClient class. Initiates a connexion with the AS/400 server.

Params:

partition_name

DNS name (name of the partition) of the remote AS/400 server.

port

Port used for the data exchange between the client and the server.

username

Username of the AS/400 profile used for connexion.

password

Password of the AS/400 profile used for connexion.

id_client

ID of the client account on the DIPS website.

online_version

Set to true if you want to use the online version of Peasys (<see cref=“dips400.com/docs/connexion”/>).

retrieve_statistics

Set to true if you want the statistics of the license key use to be collect.

raises a PeaInvalidCredentialsError if credentials are empty. raises a PeaConnexionError if an error occured during the connexion process. raises a PeaInvalidCredentialsError if IBMi credentials are invalid.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/pea_client.rb', line 25

def initialize(ip_adress, partition_name, port, username, password, id_client, online_version, retrieve_statistics)

    if ip_adress.empty? || username.empty? || password.empty?
        raise PeaInvalidCredentialsError.new("Parameters of the PeaClient should not be either null or empty")
    end

    @ip_adress = ip_adress
    @id_client = id_client
    @partition_name = partition_name
    @username = username
    @password = password
    @port = port
    @online_version = online_version
    @retrieve_statistics = retrieve_statistics
    @connexion_status = "ds"
    @connexion_message = "ds"

    token = "xqdsg27010wmca6052009050000000IDSP1tiupozxreybjhlk"
    if online_version
        begin
            uri = URI("https://dips400.com/api/license-key/retrieve-token/#{partition_name}/#{id_client}")
            res = Net::HTTP.get_response(uri)

            data = JSON.parse(res.body)
            token = data["token"]
            is_valid = data["isValid"]

            if not(is_valid)
                raise PeaInvalidLicenseKeyError.new("Your subscription is not valid, visit https://dips400.com/account/subscriptions for more information.")
            end

        rescue PeaInvalidLicenseKeyError => e
            raise e
        rescue StandardError => error
            # If dips400.com doesn't respond, let's try an affline verification with the offline token
        end
    end
    
    begin
        @tcp_client = TCPSocket.new ip_adress, port
    rescue => error
        raise PeaConnexionError.new(error.full_message)
    else
         = username.ljust(10, " ") + token.ljust(50, " ") + password
        @tcp_client.send(, 0)
        @connexion_status = @tcp_client.read(1)

        case @connexion_status
        when "1"
            @connexion_message = "Connected"
            @connexion_status = 1
        when "2"
            @connexion_message = "Unable to set profile, check profile validity."
            @connexion_status = 2
            raise PeaConnexionError.new("Unable to set profile, check profile validity.")
        when "3"
            @connexion_message = "Invalid credential"
            @connexion_status = 1
            raise PeaInvalidCredentialsError.new("Invalid userName or password, check again")
        when "B"
            @connexion_message = "Peasys Online : your token connexion is no longer valid, retry to connect."
            @connexion_status = 5
            raise PeaConnexionError.new("Peasys Online : your token connexion is no longer valid, retry to connect.")
        when "D"
            @connexion_message = "Peasys Online : the partition name you provided doesn't match the actual name of the machine."
            @connexion_status = 6
            raise PeaConnexionError.new("Peasys Online : the partition name you provided doesn't match the actual name of the machine.")
        when "E"
            @connexion_message = "You reached the max number of simultaneously connected peasys users for that partition and license key. Contact us for upgrading your license."
            @connexion_status = 7
            raise PeaConnexionError.new("You reached the max number of simultaneously connected peasys users for that partition and license key. Contact us for upgrading your license.")
        when "F"
            @connexion_message = "Your license is no longer valid. Subscribe to another license in order to continue using Peasys."
            @connexion_status = 8
            raise PeaConnexionError.new("Your license is no longer valid. Subscribe to another license in order to continue using Peasys.")
        when "0" , "A" , "C" , "G"
            @connexion_message = "Error linked to DIPS source code. Please, contact us immediatly to fix the issue."
            @connexion_status = -1
            raise PeaConnexionError.new("Error linked to DIPS source code. Please, contact us immediatly to fix the issue.")
        else
            raise PeaConnexionError.new("Exception during connexion process, contact us for more informations")
        end
    end
end

Instance Method Details

#connexion_messageObject



376
377
378
# File 'lib/pea_client.rb', line 376

def connexion_message
    @connexion_message
end

#connexion_statusObject



372
373
374
# File 'lib/pea_client.rb', line 372

def connexion_status
    @connexion_status
end

#disconnectObject

Closes the TCP connexion with the server.



343
344
345
346
# File 'lib/pea_client.rb', line 343

def disconnect()
    @tcp_client.send("stopdipsjbiemg", 0)
    @tcp_client.close()
end

#execute_alter(query, retrieve_table_schema) ⇒ Object

Sends the ALTER SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the ALTER keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with ALTER.



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/pea_client.rb', line 227

def execute_alter(query, retrieve_table_schema)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("ALTER")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the ALTER SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)

    tb_schema = Hash.new()
    if retrieve_table_schema
        query_words = query.split(' ')
        names = query_words[2].split('/')
        tb_query = """SELECT COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, LENGTH, NUMERIC_SCALE, IS_NULLABLE, IS_UPDATABLE, NUMERIC_PRECISION FROM 
        QSYS2.SYSCOLUMNS WHERE SYSTEM_TABLE_NAME = '""" + names[1].upcase + "' AND SYSTEM_TABLE_SCHEMA = '" + names[0].upcase + "'"

        result, list_name, nb_row, sql_state, sql_message = build_data(tb_query)

        for i in 0..(nb_row - 1) do
            tb_schema["column_name"] = ColumnInfo.new(result["COLUMN_NAME"][i], result["ORDINAL_POSITION"][i], result["DATA_TYPE"][i], result["LENGTH"][i], 
                result["NUMERIC_SCALE"][i], result["IS_NULLABLE"][i], result["IS_UPDATABLE"][i], result["NUMERIC_PRECISION"][i])
        end
    end
    
    return PeaAlterResponse.new(sql_message.eql?("00000"), sql_message, sql_state, tb_schema)
end

#execute_command(command) ⇒ Object

Sends a OS/400 command to the server and retreives the potential warning messages.

Params:

command

The command that will be sent to the server.



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/pea_client.rb', line 321

def execute_command(command)
    data = retrieve_data("exas" + command + @@end_pack)
    description_offset = 112
    result = Array.new()

    /C[A-Z]{2}[0-9]{4}/.match(data) do |m|
        
        if !m[0].start_with?("CPI") && m.offset(0)[0] + description_offset < data.length
            description = data[m.offset(0)[0] + description_offset..(data.length - (m.offset(0)[0] + description_offset))]
            description = description[0..description.index(".")]
            description = description.gsub(/[^a-zA-Z0-9 ._'*:-]/, '')
        end

        result.append(m[0] + " " + description)

    end
    return PeaCommandResponse.new(result)
end

#execute_create(query) ⇒ Object

Sends the CREATE SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the CREATE keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with CREATE.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/pea_client.rb', line 161

def execute_create(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("CREATE")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the CREATE SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)

    query_words = query.split(' ')
    tb_schema = Hash.new()
    if query_words[1].upcase.eql?("TABLE") 
        names = query_words[2].split('/')
        tb_query = """SELECT COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, LENGTH, NUMERIC_SCALE, IS_NULLABLE, IS_UPDATABLE, NUMERIC_PRECISION FROM 
        QSYS2.SYSCOLUMNS WHERE SYSTEM_TABLE_NAME = '""" + names[1].upcase + "' AND SYSTEM_TABLE_SCHEMA = '" + names[0].upcase + "'"

        result, list_name, nb_row, sql_state, sql_message = build_data(tb_query)

        for i in 0..(nb_row - 1) do
            tb_schema["column_name"] = ColumnInfo.new(result["COLUMN_NAME"][i], result["ORDINAL_POSITION"][i], result["DATA_TYPE"][i], result["LENGTH"][i], 
                result["NUMERIC_SCALE"][i], result["IS_NULLABLE"][i], result["IS_UPDATABLE"][i], result["NUMERIC_PRECISION"][i])
        end
    end

    case query_words[1].upcase
    when "TABLE"
        return PeaCreateResponse.new(sql_message.eql?("00000"), sql_message, sql_state, "", "", tb_schema)
    when "INDEX"
        return PeaCreateResponse.new(sql_message.eql?("00000"), sql_message, sql_state, "", query_words[2], "")
    when "DATABASE"
        return PeaCreateResponse.new(sql_message.eql?("00000"), sql_message, sql_state, query_words[2], "", "")
    else
        raise PeaConnexionError.new("Exception during connexion process, contact us for more informations")
    end
end

#execute_delete(query) ⇒ Object

Sends the DELETE SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the DELETE keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with DELETE.



206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/pea_client.rb', line 206

def execute_delete(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("DELETE")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the DELETE SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)
    
    return PeaDeleteResponse.new(sql_message.eql?("00000"), sql_message, sql_state, nb_row)
end

#execute_drop(query) ⇒ Object

Sends the DROP SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the DROP keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with DROP.



263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/pea_client.rb', line 263

def execute_drop(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("DROP")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the DROP SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)
    
    return PeaDropResponse.new(sql_message.eql?("00000"), sql_message, sql_state)
end

#execute_insert(query) ⇒ Object

Sends the INSERT SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the INSERT keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with INSERT.



284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/pea_client.rb', line 284

def execute_insert(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("INSERT")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the INSERT SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)
    
    return PeaInsertResponse.new(sql_message.eql?("00000"), sql_message, sql_state, nb_row)
end

#execute_select(query) ⇒ Object

Sends the SELECT SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the SELECT keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with SELECT.



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/pea_client.rb', line 118

def execute_select(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("SELECT")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the SELECT SQL keyword")
    end

    result, list_name, nb_row, sql_state, sql_message = build_data(query)
    
    return PeaSelectResponse.new(sql_message.eql?("00000"), sql_message, sql_state, result, nb_row, list_name)
end

#execute_sql(query) ⇒ Object

Sends the SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query.

raises a PeaInvalidSyntaxQueryError if query is empty.



305
306
307
308
309
310
311
312
313
# File 'lib/pea_client.rb', line 305

def execute_sql(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end

    nb_row, sql_state, sql_message = modify_table(query)
    
    return PeaResponse.new(sql_message.eql?("00000"), sql_message, sql_state)
end

#execute_update(query) ⇒ Object

Sends the UPDATE SQL query to the server that execute it and retrieve the desired data.

Params:

query

SQL query that should start with the UPDATE keyword.

raises a PeaInvalidSyntaxQueryError if query is empty or doesn’t start with UPDATE.



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/pea_client.rb', line 139

def execute_update(query)
    if query.empty?
        raise PeaInvalidSyntaxQueryError.new("Query should not be either null or empty")
    end
    if !query.upcase.start_with?("UPDATE")
        raise PeaInvalidSyntaxQueryError.new("Query should start with the UPDATE SQL keyword")
    end

    nb_row, sql_state, sql_message = modify_table(query)
    has_succeeded = sql_state.eql?("00000") || sql_state.eql?("01504")
    
    return PeaUpdateResponse.new(has_succeeded, sql_message, sql_state, nb_row)
end

#id_clientObject



348
349
350
# File 'lib/pea_client.rb', line 348

def id_client
    @id_client
end

#online_versionObject



364
365
366
# File 'lib/pea_client.rb', line 364

def online_version
    @online_version
end

#partition_nameObject



352
353
354
# File 'lib/pea_client.rb', line 352

def  partition_name
    @partition_name
end

#portObject



360
361
362
# File 'lib/pea_client.rb', line 360

def port
    @port
end

#retrieve_statisticsObject



368
369
370
# File 'lib/pea_client.rb', line 368

def retrieve_statistics
    @retrieve_statistics
end

#usernameObject



356
357
358
# File 'lib/pea_client.rb', line 356

def username
    @username
end